Micron Document
🎖️GitЯра🎖️

Node / meshtastic / Meshtastic-Android / files / core / service / src / androidMain / kotlin / org / meshtastic / core / service / MeshNotificationManagerImpl.kt

Displaying Raw • Download

core/service/src/androidMain/kotlin/org/meshtastic/core/service/MeshNotificationManagerImpl.kt fix/qr-error-correction (7b45f84f) Text, 51.21 KB

T8b949e/*
* Copyright (c) 2026 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
Tff7b72package T7ee787org.meshtastic.core.service

Tff7b72import T7ee787android.app.Notification
Tff7b72import T7ee787android.app.NotificationChannel
Tff7b72import T7ee787android.app.NotificationManager
Tff7b72import T7ee787android.app.PendingIntent
Tff7b72import T7ee787android.app.TaskStackBuilder
Tff7b72import T7ee787android.content.ContentResolver.SCHEME_ANDROID_RESOURCE
Tff7b72import T7ee787android.content.Context
Tff7b72import T7ee787android.content.Intent
Tff7b72import T7ee787android.media.AudioAttributes
Tff7b72import T7ee787android.media.RingtoneManager
Tff7b72import T7ee787androidx.core.app.NotificationCompat
Tff7b72import T7ee787androidx.core.app.Person
Tff7b72import T7ee787androidx.core.app.RemoteInput
Tff7b72import T7ee787androidx.core.content.LocusIdCompat
Tff7b72import T7ee787androidx.core.content.getSystemService
Tff7b72import T7ee787androidx.core.graphics.drawable.IconCompat
Tff7b72import T7ee787androidx.core.net.toUri
Tff7b72import T7ee787co.touchlab.kermit.Logger
Tff7b72import T7ee787kotlinx.coroutines.channels.BufferOverflow
Tff7b72import T7ee787kotlinx.coroutines.flow.MutableSharedFlow
Tff7b72import T7ee787kotlinx.coroutines.flow.collectLatest
Tff7b72import T7ee787kotlinx.coroutines.flow.first
Tff7b72import T7ee787kotlinx.coroutines.launch
Tff7b72import T7ee787org.jetbrains.compose.resources.StringResource
Tff7b72import T7ee787org.koin.core.annotation.Single
Tff7b72import T7ee787org.meshtastic.core.common.di.ServiceScope
Tff7b72import T7ee787org.meshtastic.core.common.util.NumberFormatter
Tff7b72import T7ee787org.meshtastic.core.common.util.nowMillis
Tff7b72import T7ee787org.meshtastic.core.common.util.safeCatching
Tff7b72import T7ee787org.meshtastic.core.model.Channel
Tff7b72import T7ee787org.meshtastic.core.model.ConnectionState
Tff7b72import T7ee787org.meshtastic.core.model.Message
Tff7b72import T7ee787org.meshtastic.core.model.Node
Tff7b72import T7ee787org.meshtastic.core.model.NodeAddress
Tff7b72import T7ee787org.meshtastic.core.model.util.formatUptime
Tff7b72import T7ee787org.meshtastic.core.navigation.DEEP_LINK_BASE_URI
Tff7b72import T7ee787org.meshtastic.core.repository.MeshNotificationManager
Tff7b72import T7ee787org.meshtastic.core.repository.NodeRepository
Tff7b72import T7ee787org.meshtastic.core.repository.PacketRepository
Tff7b72import T7ee787org.meshtastic.core.repository.RadioConfigRepository
Tff7b72import T7ee787org.meshtastic.core.repository.SERVICE_NOTIFY_ID
Tff7b72import T7ee787org.meshtastic.core.resources.R.drawable
Tff7b72import T7ee787org.meshtastic.core.resources.R.raw
Tff7b72import T7ee787org.meshtastic.core.resources.Res
Tff7b72import T7ee787org.meshtastic.core.resources.channel
Tff7b72import T7ee787org.meshtastic.core.resources.client_notification
Tff7b72import T7ee787org.meshtastic.core.resources.connected
Tff7b72import T7ee787org.meshtastic.core.resources.connecting
Tff7b72import T7ee787org.meshtastic.core.resources.device_sleeping
Tff7b72import T7ee787org.meshtastic.core.resources.disconnected
Tff7b72import T7ee787org.meshtastic.core.resources.getString
Tff7b72import T7ee787org.meshtastic.core.resources.getStringSuspend
Tff7b72import T7ee787org.meshtastic.core.resources.local_stats_bad
Tff7b72import T7ee787org.meshtastic.core.resources.local_stats_battery
Tff7b72import T7ee787org.meshtastic.core.resources.local_stats_diagnostics_prefix
Tff7b72import T7ee787org.meshtastic.core.resources.local_stats_dropped
Tff7b72import T7ee787org.meshtastic.core.resources.local_stats_heap
Tff7b72import T7ee787org.meshtastic.core.resources.local_stats_heap_value
Tff7b72import T7ee787org.meshtastic.core.resources.local_stats_nodes
Tff7b72import T7ee787org.meshtastic.core.resources.local_stats_noise
Tff7b72import T7ee787org.meshtastic.core.resources.local_stats_relays
Tff7b72import T7ee787org.meshtastic.core.resources.local_stats_traffic
Tff7b72import T7ee787org.meshtastic.core.resources.local_stats_uptime
Tff7b72import T7ee787org.meshtastic.core.resources.local_stats_utilization
Tff7b72import T7ee787org.meshtastic.core.resources.low_battery_message
Tff7b72import T7ee787org.meshtastic.core.resources.low_battery_title
Tff7b72import T7ee787org.meshtastic.core.resources.mark_as_read
Tff7b72import T7ee787org.meshtastic.core.resources.meshtastic_alerts_notifications
Tff7b72import T7ee787org.meshtastic.core.resources.meshtastic_app_name
Tff7b72import T7ee787org.meshtastic.core.resources.meshtastic_broadcast_notifications
Tff7b72import T7ee787org.meshtastic.core.resources.meshtastic_low_battery_notifications
Tff7b72import T7ee787org.meshtastic.core.resources.meshtastic_low_battery_temporary_remote_notifications
Tff7b72import T7ee787org.meshtastic.core.resources.meshtastic_messages_notifications
Tff7b72import T7ee787org.meshtastic.core.resources.meshtastic_new_nodes_notifications
Tff7b72import T7ee787org.meshtastic.core.resources.meshtastic_service_notifications
Tff7b72import T7ee787org.meshtastic.core.resources.meshtastic_waypoints_notifications
Tff7b72import T7ee787org.meshtastic.core.resources.new_node_seen
Tff7b72import T7ee787org.meshtastic.core.resources.no_local_stats
Tff7b72import T7ee787org.meshtastic.core.resources.powered
Tff7b72import T7ee787org.meshtastic.core.resources.reply
Tff7b72import T7ee787org.meshtastic.core.resources.unknown_username
Tff7b72import T7ee787org.meshtastic.core.resources.you
Tff7b72import T7ee787org.meshtastic.core.service.MarkAsReadReceiver.Companion.MARK_AS_READ_ACTION
Tff7b72import T7ee787org.meshtastic.core.service.ReactionReceiver.Companion.REACT_ACTION
Tff7b72import T7ee787org.meshtastic.core.service.ReplyReceiver.Companion.KEY_TEXT_REPLY
Tff7b72import T7ee787org.meshtastic.proto.ClientNotification
Tff7b72import T7ee787org.meshtastic.proto.DeviceMetrics
Tff7b72import T7ee787org.meshtastic.proto.LocalStats
Tff7b72import T7ee787org.meshtastic.proto.Telemetry
Tff7b72import T7ee787java.util.concurrent.ConcurrentHashMap
Tff7b72import T7ee787kotlin.time.Duration.Companion.minutes

T8b949e/**
* Manages the creation and display of all app notifications.
*
* This class centralizes notification logic, including channel creation, builder configuration, and displaying
* notifications for various events like new messages, alerts, and service status changes.
*/
Tf0883e@SuppressTb4b4b4(Ta5d6ff"Ta5d6ffTooManyFunctionsTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffLongParameterListTa5d6ff"Tb4b4b4, Ta5d6ff"Ta5d6ffLargeClassTa5d6ff"Tb4b4b4)
Tf0883e@Single
Tff7b72class T56d364MeshNotificationManagerImplTb4b4b4(
Tff7b72private Tff7b72val Te6edf3contextTb4b4b4: Te6edf3ContextTb4b4b4,
Tff7b72private Tff7b72val Te6edf3packetRepositoryTb4b4b4: Te6edf3LazyTff7b72<Te6edf3PacketRepositoryTff7b72>Tb4b4b4,
Tff7b72private Tff7b72val Te6edf3nodeRepositoryTb4b4b4: Te6edf3LazyTff7b72<Te6edf3NodeRepositoryTff7b72>Tb4b4b4,
Tff7b72private Tff7b72val Te6edf3conversationShortcutPublisherTb4b4b4: Te6edf3LazyTff7b72<Te6edf3ConversationShortcutPublisherTff7b72>Tb4b4b4,
Tff7b72private Tff7b72val Te6edf3radioConfigRepositoryTb4b4b4: Te6edf3LazyTff7b72<Te6edf3RadioConfigRepositoryTff7b72>Tb4b4b4,
Tff7b72private Tff7b72val Te6edf3scopeTb4b4b4: Te6edf3ServiceScopeTb4b4b4,
Tb4b4b4) Tb4b4b4: Te6edf3MeshNotificationManager Tb4b4b4{

Tff7b72private Tff7b72val Te6edf3notificationManager Tff7b72=
Te6edf3checkNotNullTb4b4b4(Te6edf3contextTb4b4b4.Te6edf3getSystemServiceTff7b72<Te6edf3NotificationManagerTff7b72>Tb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{ Ta5d6ff"Ta5d6ffNotificationManager not foundTa5d6ff" Tb4b4b4}

Tff7b72companion Tff7b72object Tb4b4b4{
Tff7b72const Tff7b72val Te6edf3MAX_BATTERY_LEVEL Tff7b72= T79c0ff1T79c0ff0T79c0ff0

T8b949e// Meshtastic brand accent (Green 500, see .skills/design-standards) — used as the notification accent color
T8b949e// (small-icon tint) and the notification LED color.
Tff7b72private Tff7b72val Te6edf3NOTIFICATION_COLOR Tff7b72= T79c0ff0Te6edf3xFF67EA94Tb4b4b4.Te6edf3toIntTb4b4b4(Tb4b4b4)
Tff7b72private Tff7b72const Tff7b72val Te6edf3MAX_HISTORY_MESSAGES Tff7b72= T79c0ff1T79c0ff0
Tff7b72private Tff7b72const Tff7b72val Te6edf3MIN_CONTEXT_MESSAGES Tff7b72= T79c0ff3
Tff7b72private Tff7b72const Tff7b72val Te6edf3SNIPPET_LENGTH Tff7b72= T79c0ff3T79c0ff0
Tff7b72private Tff7b72const Tff7b72val Te6edf3GROUP_KEY_MESSAGES Tff7b72= Ta5d6ff"Ta5d6fforg.meshtastic.app.GROUP_MESSAGESTa5d6ff"
Tff7b72private Tff7b72const Tff7b72val Te6edf3SUMMARY_ID Tff7b72= T79c0ff1
Tff7b72private Tff7b72const Tff7b72val Te6edf3STATS_UPDATE_MINUTES Tff7b72= T79c0ff1T79c0ff5
Tff7b72private Tff7b72val Te6edf3STATS_UPDATE_INTERVAL Tff7b72= Te6edf3STATS_UPDATE_MINUTESTb4b4b4.Te6edf3minutes
Tff7b72private Tff7b72const Tff7b72val Te6edf3BULLET Tff7b72= Ta5d6ff"Ta5d6ff• Ta5d6ff"

T8b949e// Notification tags namespace the numeric IDs per notification type. Without them every type shares one
T8b949e// integer ID space, so unrelated notifications can clobber each other (e.g. a node whose num == 101 would
T8b949e// overwrite the foreground-service notification, or num == 1 the group summary). notify()/cancel() must use
T8b949e// the same (tag, id) pair.
Tff7b72private Tff7b72const Tff7b72val Te6edf3TAG_MESSAGE Tff7b72= Ta5d6ff"Ta5d6ffmessageTa5d6ff"
Tff7b72private Tff7b72const Tff7b72val Te6edf3TAG_MESSAGE_SUMMARY Tff7b72= Ta5d6ff"Ta5d6ffmessage_summaryTa5d6ff"
Tff7b72private Tff7b72const Tff7b72val Te6edf3TAG_WAYPOINT Tff7b72= Ta5d6ff"Ta5d6ffwaypointTa5d6ff"
Tff7b72private Tff7b72const Tff7b72val Te6edf3TAG_ALERT Tff7b72= Ta5d6ff"Ta5d6ffalertTa5d6ff"
Tff7b72private Tff7b72const Tff7b72val Te6edf3TAG_NEW_NODE Tff7b72= Ta5d6ff"Ta5d6ffnew_nodeTa5d6ff"
Tff7b72private Tff7b72const Tff7b72val Te6edf3TAG_LOW_BATTERY Tff7b72= Ta5d6ff"Ta5d6fflow_batteryTa5d6ff"
Tff7b72private Tff7b72const Tff7b72val Te6edf3TAG_CLIENT Tff7b72= Ta5d6ff"Ta5d6ffclientTa5d6ff"
Tb4b4b4}

Tff7b72private Tff7b72data Tff7b72class T56d364ServiceNotificationSnapshotTb4b4b4(
Tff7b72val Te6edf3stateTb4b4b4: Te6edf3ConnectionStateTb4b4b4,
Tff7b72val Te6edf3localStatsTb4b4b4: Te6edf3LocalStats?Tb4b4b4,
Tff7b72val Te6edf3deviceMetricsTb4b4b4: Te6edf3DeviceMetrics?Tb4b4b4,
Tff7b72val Te6edf3previousMessageTb4b4b4: Tffa657String?Tb4b4b4,
Tff7b72val Te6edf3nextUpdateAtTb4b4b4: Tffa657LongTb4b4b4,
Tb4b4b4)

Tff7b72private Tff7b72data Tff7b72class T56d364RenderedServiceNotificationTb4b4b4(Tff7b72val Te6edf3notificationTb4b4b4: Te6edf3NotificationTb4b4b4, Tff7b72val Te6edf3messageTb4b4b4: Tffa657StringTb4b4b4)

T8b949e/**
* Caches generated avatar icons keyed by (person id + short name + colors) so a conversation rebuild does not
* re-rasterize an avatar bitmap for every message on every update. Bounded by the number of distinct nodes seen;
* entries are cheap and colors/names rarely change.
*/
Tff7b72private Tff7b72val Te6edf3personIconCache Tff7b72= Te6edf3ConcurrentHashMapTff7b72<Tffa657StringTb4b4b4, Te6edf3IconCompatTff7b72>Tb4b4b4(Tb4b4b4)

T8b949e/** Circular, node-colored avatar holding the sender's full short name (e.g. "2c3d"), not just its first letter. */
Tff7b72private Tff7b72fun Td2a8ffcachedPersonIconTb4b4b4(Te6edf3keyTb4b4b4: Tffa657StringTb4b4b4, Te6edf3shortNameTb4b4b4: Tffa657StringTb4b4b4, Te6edf3backgroundColorTb4b4b4: Tffa657IntTb4b4b4, Te6edf3foregroundColorTb4b4b4: Tffa657IntTb4b4b4) Tff7b72=
Te6edf3personIconCacheTb4b4b4.Te6edf3getOrPutTb4b4b4(Ta5d6ff"Tffd700$Te6edf3keyTa5d6ff|Tffd700$Te6edf3shortNameTa5d6ff|Tffd700$Te6edf3backgroundColorTa5d6ff|Tffd700$Te6edf3foregroundColorTa5d6ff"Tb4b4b4) Tb4b4b4{
Te6edf3PersonIconFactoryTb4b4b4.Te6edf3createLabelTb4b4b4(Te6edf3shortNameTb4b4b4, Te6edf3backgroundColorTb4b4b4, Te6edf3foregroundColorTb4b4b4, Te6edf3rounded Tff7b72= Tff7b72falseTb4b4b4)
Tb4b4b4}

T8b949e/**
* Sealed class to define the properties of each notification channel. This centralizes channel configuration and
* makes it type-safe.
*/
Tff7b72private Tff7b72sealed Tff7b72class T56d364NotificationTypeTb4b4b4(
Tff7b72val Te6edf3channelIdTb4b4b4: Tffa657StringTb4b4b4,
Tff7b72val Te6edf3channelNameResTb4b4b4: Te6edf3StringResourceTb4b4b4,
Tff7b72val Te6edf3importanceTb4b4b4: Tffa657IntTb4b4b4,
Tb4b4b4) Tb4b4b4{
Tff7b72object T56d364ServiceState Tb4b4b4:
Te6edf3NotificationTypeTb4b4b4(
Te6edf3NotificationChannelsTb4b4b4.Te6edf3SERVICETb4b4b4,
Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3meshtastic_service_notificationsTb4b4b4,
Te6edf3NotificationManagerTb4b4b4.Te6edf3IMPORTANCE_MINTb4b4b4,
Tb4b4b4)

Tff7b72object T56d364DirectMessage Tb4b4b4:
Te6edf3NotificationTypeTb4b4b4(
Te6edf3NotificationChannelsTb4b4b4.Te6edf3MESSAGESTb4b4b4,
Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3meshtastic_messages_notificationsTb4b4b4,
Te6edf3NotificationManagerTb4b4b4.Te6edf3IMPORTANCE_HIGHTb4b4b4,
Tb4b4b4)

Tff7b72object T56d364BroadcastMessage Tb4b4b4:
Te6edf3NotificationTypeTb4b4b4(
Te6edf3NotificationChannelsTb4b4b4.Te6edf3BROADCASTSTb4b4b4,
Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3meshtastic_broadcast_notificationsTb4b4b4,
Te6edf3NotificationManagerTb4b4b4.Te6edf3IMPORTANCE_DEFAULTTb4b4b4,
Tb4b4b4)

Tff7b72object T56d364Waypoint Tb4b4b4:
Te6edf3NotificationTypeTb4b4b4(
Te6edf3NotificationChannelsTb4b4b4.Te6edf3WAYPOINTSTb4b4b4,
Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3meshtastic_waypoints_notificationsTb4b4b4,
Te6edf3NotificationManagerTb4b4b4.Te6edf3IMPORTANCE_DEFAULTTb4b4b4,
Tb4b4b4)

Tff7b72object T56d364Alert Tb4b4b4:
Te6edf3NotificationTypeTb4b4b4(
Te6edf3NotificationChannelsTb4b4b4.Te6edf3ALERTSTb4b4b4,
Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3meshtastic_alerts_notificationsTb4b4b4,
Te6edf3NotificationManagerTb4b4b4.Te6edf3IMPORTANCE_HIGHTb4b4b4,
Tb4b4b4)

Tff7b72object T56d364NewNode Tb4b4b4:
Te6edf3NotificationTypeTb4b4b4(
Te6edf3NotificationChannelsTb4b4b4.Te6edf3NEW_NODESTb4b4b4,
Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3meshtastic_new_nodes_notificationsTb4b4b4,
Te6edf3NotificationManagerTb4b4b4.Te6edf3IMPORTANCE_DEFAULTTb4b4b4,
Tb4b4b4)

Tff7b72object T56d364LowBatteryLocal Tb4b4b4:
Te6edf3NotificationTypeTb4b4b4(
Te6edf3NotificationChannelsTb4b4b4.Te6edf3LOW_BATTERYTb4b4b4,
Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3meshtastic_low_battery_notificationsTb4b4b4,
Te6edf3NotificationManagerTb4b4b4.Te6edf3IMPORTANCE_DEFAULTTb4b4b4,
Tb4b4b4)

Tff7b72object T56d364LowBatteryRemote Tb4b4b4:
Te6edf3NotificationTypeTb4b4b4(
Te6edf3NotificationChannelsTb4b4b4.Te6edf3LOW_BATTERY_REMOTETb4b4b4,
Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3meshtastic_low_battery_temporary_remote_notificationsTb4b4b4,
Te6edf3NotificationManagerTb4b4b4.Te6edf3IMPORTANCE_DEFAULTTb4b4b4,
Tb4b4b4)

Tff7b72object T56d364Client Tb4b4b4:
Te6edf3NotificationTypeTb4b4b4(
Te6edf3NotificationChannelsTb4b4b4.Te6edf3CLIENTTb4b4b4,
Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3client_notificationTb4b4b4,
Te6edf3NotificationManagerTb4b4b4.Te6edf3IMPORTANCE_HIGHTb4b4b4,
Tb4b4b4)

Tff7b72companion Tff7b72object Tb4b4b4{
T8b949e// A list of all types for easy initialization.
Tff7b72fun Td2a8ffallTypesTb4b4b4(Tb4b4b4) Tff7b72= Te6edf3listOfTb4b4b4(
Te6edf3ServiceStateTb4b4b4,
Te6edf3DirectMessageTb4b4b4,
Te6edf3BroadcastMessageTb4b4b4,
Te6edf3WaypointTb4b4b4,
Te6edf3AlertTb4b4b4,
Te6edf3NewNodeTb4b4b4,
Te6edf3LowBatteryLocalTb4b4b4,
Te6edf3LowBatteryRemoteTb4b4b4,
Te6edf3ClientTb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tb4b4b4}

Tff7b72override Tff7b72fun Td2a8ffclearNotificationsTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3notificationManagerTb4b4b4.Te6edf3cancelAllTb4b4b4(Tb4b4b4)
Tb4b4b4}

T8b949e/**
* Creates all necessary notification channels on devices running Android O or newer. This should be called once
* when the service is created.
*
* Deliberately blocking (Main-thread, one-time cost): the orchestrator posts the foreground-service notification
* synchronously right after this returns, so channels must exist before then — do not lazy-gate this into the
* suspend notify paths. Blocking [getString] is safe here only because Main is not a Dispatchers.Default worker.
*/
Tff7b72override Tff7b72fun Td2a8ffinitChannelsTb4b4b4(Tb4b4b4) Tb4b4b4{
Te6edf3notificationManagerTb4b4b4.Te6edf3removeLegacyCategoryChannelsTb4b4b4(Tb4b4b4)
Te6edf3NotificationTypeTb4b4b4.Te6edf3allTypesTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3forEach Tb4b4b4{ Te6edf3type Tff7b72-Tff7b72> Te6edf3createNotificationChannelTb4b4b4(Te6edf3typeTb4b4b4) Tb4b4b4}
Tb4b4b4}

Tff7b72private Tff7b72fun Td2a8ffcreateNotificationChannelTb4b4b4(Te6edf3typeTb4b4b4: Te6edf3NotificationTypeTb4b4b4) Tb4b4b4{
Tff7b72if Tb4b4b4(Te6edf3notificationManagerTb4b4b4.Te6edf3getNotificationChannelTb4b4b4(Te6edf3typeTb4b4b4.Te6edf3channelIdTb4b4b4) Tff7b72!Tff7b72= Tff7b72nullTb4b4b4) Tff7b72return

Tff7b72val Te6edf3channelName Tff7b72= Te6edf3getStringTb4b4b4(Te6edf3typeTb4b4b4.Te6edf3channelNameResTb4b4b4)
Tff7b72val Te6edf3channel Tff7b72=
Te6edf3NotificationChannelTb4b4b4(Te6edf3typeTb4b4b4.Te6edf3channelIdTb4b4b4, Te6edf3channelNameTb4b4b4, Te6edf3typeTb4b4b4.Te6edf3importanceTb4b4b4)Tb4b4b4.Te6edf3apply Tb4b4b4{
Te6edf3lightColor Tff7b72= Te6edf3NOTIFICATION_COLOR
Te6edf3lockscreenVisibility Tff7b72= Te6edf3NotificationTb4b4b4.Te6edf3VISIBILITY_PUBLIC T8b949e// Default, can be overridden

T8b949e// Type-specific configurations
Tff7b72when Tb4b4b4(Te6edf3typeTb4b4b4) Tb4b4b4{
Te6edf3NotificationTypeTb4b4b4.Te6edf3ServiceState Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3lockscreenVisibility Tff7b72= Te6edf3NotificationTb4b4b4.Te6edf3VISIBILITY_PRIVATE
Tb4b4b4}

Te6edf3NotificationTypeTb4b4b4.Te6edf3DirectMessageTb4b4b4,
Te6edf3NotificationTypeTb4b4b4.Te6edf3BroadcastMessageTb4b4b4,
Te6edf3NotificationTypeTb4b4b4.Te6edf3WaypointTb4b4b4,
Te6edf3NotificationTypeTb4b4b4.Te6edf3NewNodeTb4b4b4,
Te6edf3NotificationTypeTb4b4b4.Te6edf3LowBatteryLocalTb4b4b4,
Te6edf3NotificationTypeTb4b4b4.Te6edf3LowBatteryRemoteTb4b4b4,
Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3setShowBadgeTb4b4b4(Tff7b72trueTb4b4b4)
Te6edf3setSoundTb4b4b4(
Te6edf3RingtoneManagerTb4b4b4.Te6edf3getDefaultUriTb4b4b4(Te6edf3RingtoneManagerTb4b4b4.Te6edf3TYPE_NOTIFICATIONTb4b4b4)Tb4b4b4,
Te6edf3AudioAttributesTb4b4b4.Te6edf3BuilderTb4b4b4(Tb4b4b4)
Tb4b4b4.Te6edf3setUsageTb4b4b4(Te6edf3AudioAttributesTb4b4b4.Te6edf3USAGE_NOTIFICATIONTb4b4b4)
Tb4b4b4.Te6edf3setContentTypeTb4b4b4(Te6edf3AudioAttributesTb4b4b4.Te6edf3CONTENT_TYPE_SONIFICATIONTb4b4b4)
Tb4b4b4.Te6edf3buildTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3type Tff7b72=Tff7b72= Te6edf3NotificationTypeTb4b4b4.Te6edf3LowBatteryRemoteTb4b4b4) Te6edf3enableVibrationTb4b4b4(Tff7b72trueTb4b4b4)
Tb4b4b4}

Te6edf3NotificationTypeTb4b4b4.Te6edf3Alert Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3setShowBadgeTb4b4b4(Tff7b72trueTb4b4b4)
Te6edf3enableLightsTb4b4b4(Tff7b72trueTb4b4b4)
Te6edf3enableVibrationTb4b4b4(Tff7b72trueTb4b4b4)
Te6edf3setBypassDndTb4b4b4(Tff7b72trueTb4b4b4)
Tff7b72val Te6edf3alertSoundUri Tff7b72=
Ta5d6ff"Tffd700${Te6edf3SCHEME_ANDROID_RESOURCETffd700}Ta5d6ff://Tffd700${Te6edf3contextTb4b4b4.Te6edf3packageNameTffd700}Ta5d6ff/Tffd700${Te6edf3rawTb4b4b4.Te6edf3meshtastic_alertTffd700}Ta5d6ff"Tb4b4b4.Te6edf3toUriTb4b4b4(Tb4b4b4)
Te6edf3setSoundTb4b4b4(
Te6edf3alertSoundUriTb4b4b4,
Te6edf3AudioAttributesTb4b4b4.Te6edf3BuilderTb4b4b4(Tb4b4b4)
Tb4b4b4.Te6edf3setUsageTb4b4b4(Te6edf3AudioAttributesTb4b4b4.Te6edf3USAGE_ALARMTb4b4b4) T8b949e// More appropriate for an alert
Tb4b4b4.Te6edf3setContentTypeTb4b4b4(Te6edf3AudioAttributesTb4b4b4.Te6edf3CONTENT_TYPE_SONIFICATIONTb4b4b4)
Tb4b4b4.Te6edf3buildTb4b4b4(Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tb4b4b4}

Te6edf3NotificationTypeTb4b4b4.Te6edf3Client Tff7b72-Tff7b72> Tb4b4b4{
Te6edf3setShowBadgeTb4b4b4(Tff7b72trueTb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}
Te6edf3notificationManagerTb4b4b4.Te6edf3createNotificationChannelTb4b4b4(Te6edf3channelTb4b4b4)
Tb4b4b4}

Tff7b72private Tff7b72val Te6edf3serviceNotificationLock Tff7b72= Tffa657AnyTb4b4b4(Tb4b4b4)
Tff7b72private Tff7b72val Te6edf3applicationLabelTb4b4b4: Tffa657String Tff7b72by Te6edf3lazy Tb4b4b4{
Te6edf3contextTb4b4b4.Te6edf3applicationInfoTb4b4b4.Te6edf3loadLabelTb4b4b4(Te6edf3contextTb4b4b4.Te6edf3packageManagerTb4b4b4)Tb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3ifBlank Tb4b4b4{ Te6edf3contextTb4b4b4.Te6edf3packageName Tb4b4b4}
Tb4b4b4}
Tff7b72private Tff7b72var Te6edf3cachedDeviceMetricsTb4b4b4: Te6edf3DeviceMetrics? Tff7b72= Tff7b72null
Tff7b72private Tff7b72var Te6edf3cachedLocalStatsTb4b4b4: Te6edf3LocalStats? Tff7b72= Tff7b72null
Tff7b72private Tff7b72var Te6edf3nextStatsUpdateMillisTb4b4b4: Tffa657Long Tff7b72= T79c0ff0
Tff7b72private Tff7b72var Te6edf3cachedMessageTb4b4b4: Tffa657String? Tff7b72= Tff7b72null
Tff7b72private Tff7b72var Te6edf3cachedServiceNotificationTb4b4b4: Te6edf3Notification? Tff7b72= Tff7b72null
Tff7b72private Tff7b72val Te6edf3serviceNotificationSnapshots Tff7b72=
Te6edf3MutableSharedFlowTff7b72<Te6edf3ServiceNotificationSnapshotTff7b72>Tb4b4b4(Te6edf3replay Tff7b72= T79c0ff1Tb4b4b4, Te6edf3onBufferOverflow Tff7b72= Te6edf3BufferOverflowTb4b4b4.Te6edf3DROP_OLDESTTb4b4b4)

Tff7b72init Tb4b4b4{
Te6edf3scopeTb4b4b4.Te6edf3launch Tb4b4b4{ Te6edf3serviceNotificationSnapshotsTb4b4b4.Te6edf3collectLatestTb4b4b4(Tff7b72::Te6edf3renderAndPostServiceNotificationTb4b4b4) Tb4b4b4}
Tb4b4b4}

T8b949e/**
* Returns the last-built service state notification, or an immediately available application-label fallback. This
* method is used by [MeshService] for [android.app.Service.startForeground], so it must not wait for Compose
* Multiplatform resource loading.
*/
Tff7b72fun Td2a8ffgetServiceNotificationTb4b4b4(Tb4b4b4)Tb4b4b4: Te6edf3Notification Tb4b4b4{
Tff7b72val Te6edf3cached Tff7b72= Te6edf3synchronizedTb4b4b4(Te6edf3serviceNotificationLockTb4b4b4) Tb4b4b4{ Te6edf3cachedServiceNotification Tb4b4b4}
Tff7b72return Te6edf3cached Tff7b72?: Te6edf3createServiceStateNotificationTb4b4b4(Te6edf3name Tff7b72= Te6edf3applicationLabelTb4b4b4, Te6edf3message Tff7b72= Tff7b72nullTb4b4b4, Te6edf3nextUpdateAt Tff7b72= T79c0ff0Tb4b4b4)
Tb4b4b4}

T8b949e// region Public Notification Methods
Tff7b72override Tff7b72fun Td2a8ffupdateServiceStateNotificationTb4b4b4(Te6edf3stateTb4b4b4: Te6edf3ConnectionStateTb4b4b4, Te6edf3telemetryTb4b4b4: Te6edf3Telemetry?Tb4b4b4) Tb4b4b4{
Te6edf3synchronizedTb4b4b4(Te6edf3serviceNotificationLockTb4b4b4) Tb4b4b4{
Te6edf3serviceNotificationSnapshotsTb4b4b4.Te6edf3tryEmitTb4b4b4(Te6edf3captureServiceNotificationSnapshotTb4b4b4(Te6edf3stateTb4b4b4, Te6edf3telemetryTb4b4b4)Tb4b4b4)
Tb4b4b4}
Tb4b4b4}

T8b949e/**
* Renders service notifications in one ordered collector. [collectLatest] cancels obsolete resource work and does
* not start the next renderer until the previous block has completed, so Binder notification posts cannot overtake
* one another and leave stale text visible.
*/
Tff7b72private Tff7b72suspend Tff7b72fun Td2a8ffrenderAndPostServiceNotificationTb4b4b4(Te6edf3snapshotTb4b4b4: Te6edf3ServiceNotificationSnapshotTb4b4b4) Tb4b4b4{
Te6edf3safeCatching Tb4b4b4{
Tff7b72val Te6edf3rendered Tff7b72= Te6edf3renderServiceNotificationTb4b4b4(Te6edf3snapshotTb4b4b4)
Te6edf3postServiceNotificationTb4b4b4(Te6edf3renderedTb4b4b4.Te6edf3notificationTb4b4b4, Te6edf3renderedTb4b4b4.Te6edf3messageTb4b4b4)
Tb4b4b4}
Tb4b4b4.Te6edf3onFailure Tb4b4b4{ Te6edf3ex Tff7b72-Tff7b72>
Te6edf3LoggerTb4b4b4.Te6edf3eTb4b4b4(Te6edf3exTb4b4b4) Tb4b4b4{ Ta5d6ff"Ta5d6ffFailed to render service notification resourcesTa5d6ff" Tb4b4b4}
Tff7b72val Te6edf3fallback Tff7b72=
Te6edf3createServiceStateNotificationTb4b4b4(
Te6edf3name Tff7b72= Te6edf3applicationLabelTb4b4b4,
Te6edf3message Tff7b72= Te6edf3snapshotTb4b4b4.Te6edf3previousMessageTb4b4b4,
Te6edf3nextUpdateAt Tff7b72= Te6edf3snapshotTb4b4b4.Te6edf3nextUpdateAtTb4b4b4,
Tb4b4b4)
Te6edf3safeCatching Tb4b4b4{ Te6edf3postServiceNotificationTb4b4b4(Te6edf3fallbackTb4b4b4, Te6edf3snapshotTb4b4b4.Te6edf3previousMessageTb4b4b4) Tb4b4b4}
Tb4b4b4.Te6edf3onFailure Tb4b4b4{ Te6edf3LoggerTb4b4b4.Te6edf3eTb4b4b4(Tffa657itTb4b4b4) Tb4b4b4{ Ta5d6ff"Ta5d6ffFailed to post fallback service notificationTa5d6ff" Tb4b4b4} Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

T8b949e/** Updates the foreground fallback cache before posting the same notification through Android's Binder API. */
Tff7b72private Tff7b72fun Td2a8ffpostServiceNotificationTb4b4b4(Te6edf3notificationTb4b4b4: Te6edf3NotificationTb4b4b4, Te6edf3messageTb4b4b4: Tffa657String?Tb4b4b4) Tb4b4b4{
Te6edf3synchronizedTb4b4b4(Te6edf3serviceNotificationLockTb4b4b4) Tb4b4b4{
Te6edf3cachedMessage Tff7b72= Te6edf3message
Te6edf3cachedServiceNotification Tff7b72= Te6edf3notification
Tb4b4b4}
Te6edf3notificationManagerTb4b4b4.Te6edf3notifyTb4b4b4(Te6edf3SERVICE_NOTIFY_IDTb4b4b4, Te6edf3notificationTb4b4b4)
Tb4b4b4}

Tff7b72private Tff7b72fun Td2a8ffcaptureServiceNotificationSnapshotTb4b4b4(
Te6edf3stateTb4b4b4: Te6edf3ConnectionStateTb4b4b4,
Te6edf3telemetryTb4b4b4: Te6edf3Telemetry?Tb4b4b4,
Tb4b4b4)Tb4b4b4: Te6edf3ServiceNotificationSnapshot Tb4b4b4{
Te6edf3telemetryTff7b72?.Te6edf3let Tb4b4b4{ Te6edf3currentTelemetry Tff7b72-Tff7b72>
Te6edf3currentTelemetryTb4b4b4.Te6edf3local_statsTff7b72?.Te6edf3let Tb4b4b4{ Te6edf3stats Tff7b72-Tff7b72>
Te6edf3cachedLocalStats Tff7b72= Te6edf3stats
Te6edf3nextStatsUpdateMillis Tff7b72= Te6edf3nowMillis Tff7b72+ Te6edf3STATS_UPDATE_INTERVALTb4b4b4.Te6edf3inWholeMilliseconds
Tb4b4b4}
Te6edf3currentTelemetryTb4b4b4.Te6edf3device_metricsTff7b72?.Te6edf3let Tb4b4b4{ Te6edf3metrics Tff7b72-Tff7b72> Te6edf3cachedDeviceMetrics Tff7b72= Te6edf3metrics Tb4b4b4}
Tb4b4b4}

T8b949e// Seed from database if the in-memory telemetry cache is empty after a process or transport restart.
Tff7b72if Tb4b4b4(Te6edf3cachedLocalStats Tff7b72=Tff7b72= Tff7b72null Tff7b72|Tff7b72| Te6edf3cachedDeviceMetrics Tff7b72=Tff7b72= Tff7b72nullTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3repo Tff7b72= Te6edf3nodeRepositoryTb4b4b4.Te6edf3value
Tff7b72val Te6edf3myNodeNum Tff7b72= Te6edf3repoTb4b4b4.Te6edf3myNodeInfoTb4b4b4.Te6edf3valueTff7b72?.Te6edf3myNodeNum
Tff7b72if Tb4b4b4(Te6edf3cachedDeviceMetrics Tff7b72=Tff7b72= Tff7b72null Tff7b72&Tff7b72& Te6edf3myNodeNum Tff7b72!Tff7b72= Tff7b72nullTb4b4b4) Tb4b4b4{
Te6edf3cachedDeviceMetrics Tff7b72= Te6edf3repoTb4b4b4.Te6edf3nodeDBbyNumTb4b4b4.Te6edf3valueTff7b72[Te6edf3myNodeNumTff7b72]Tff7b72?.Te6edf3deviceMetrics
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3cachedLocalStats Tff7b72=Tff7b72= Tff7b72nullTb4b4b4) Tb4b4b4{
Te6edf3cachedLocalStats Tff7b72= Te6edf3repoTb4b4b4.Te6edf3localStatsTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3takeIf Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3uptime_seconds Tff7b72!Tff7b72= T79c0ff0 Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

Tff7b72return Te6edf3ServiceNotificationSnapshotTb4b4b4(
Te6edf3state Tff7b72= Te6edf3stateTb4b4b4,
Te6edf3localStats Tff7b72= Te6edf3cachedLocalStatsTb4b4b4,
Te6edf3deviceMetrics Tff7b72= Te6edf3cachedDeviceMetricsTb4b4b4,
Te6edf3previousMessage Tff7b72= Te6edf3cachedMessageTb4b4b4,
Te6edf3nextUpdateAt Tff7b72= Te6edf3nextStatsUpdateMillisTb4b4b4,
Tb4b4b4)
Tb4b4b4}

Tff7b72private Tff7b72suspend Tff7b72fun Td2a8ffrenderServiceNotificationTb4b4b4(Te6edf3snapshotTb4b4b4: Te6edf3ServiceNotificationSnapshotTb4b4b4)Tb4b4b4: Te6edf3RenderedServiceNotification Tb4b4b4{
Tff7b72val Te6edf3title Tff7b72=
Tff7b72when Tb4b4b4(Te6edf3snapshotTb4b4b4.Te6edf3stateTb4b4b4) Tb4b4b4{
Tff7b72is Te6edf3ConnectionStateTb4b4b4.Te6edf3Connected Tff7b72-Tff7b72>
Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3meshtastic_app_nameTb4b4b4) Tff7b72+ Ta5d6ff"Ta5d6ff: Ta5d6ff" Tff7b72+ Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3connectedTb4b4b4)

Tff7b72is Te6edf3ConnectionStateTb4b4b4.Te6edf3Disconnected Tff7b72-Tff7b72> Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3disconnectedTb4b4b4)

Tff7b72is Te6edf3ConnectionStateTb4b4b4.Te6edf3DeviceSleep Tff7b72-Tff7b72> Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3device_sleepingTb4b4b4)

Tff7b72is Te6edf3ConnectionStateTb4b4b4.Te6edf3Connecting Tff7b72-Tff7b72> Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3connectingTb4b4b4)
Tb4b4b4}

Tff7b72val Te6edf3freshMessage Tff7b72=
Tff7b72when Tb4b4b4{
Te6edf3snapshotTb4b4b4.Te6edf3localStats Tff7b72!Tff7b72= Tff7b72null Tff7b72-Tff7b72>
Te6edf3snapshotTb4b4b4.Te6edf3localStatsTb4b4b4.Te6edf3formatToStringSuspendTb4b4b4(Te6edf3snapshotTb4b4b4.Te6edf3deviceMetricsTff7b72?.Te6edf3battery_levelTb4b4b4)

Te6edf3snapshotTb4b4b4.Te6edf3deviceMetrics Tff7b72!Tff7b72= Tff7b72null Tff7b72-Tff7b72> Te6edf3snapshotTb4b4b4.Te6edf3deviceMetricsTb4b4b4.Te6edf3formatToStringSuspendTb4b4b4(Tb4b4b4)

Tff7b72else Tff7b72-Tff7b72> Tff7b72null
Tb4b4b4}
Tff7b72val Te6edf3message Tff7b72= Te6edf3freshMessage Tff7b72?: Te6edf3snapshotTb4b4b4.Te6edf3previousMessage Tff7b72?: Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3no_local_statsTb4b4b4)
Tff7b72return Te6edf3RenderedServiceNotificationTb4b4b4(
Te6edf3notification Tff7b72= Te6edf3createServiceStateNotificationTb4b4b4(Te6edf3titleTb4b4b4, Te6edf3messageTb4b4b4, Te6edf3snapshotTb4b4b4.Te6edf3nextUpdateAtTb4b4b4)Tb4b4b4,
Te6edf3message Tff7b72= Te6edf3messageTb4b4b4,
Tb4b4b4)
Tb4b4b4}

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffupdateMessageNotificationTb4b4b4(
Te6edf3contactKeyTb4b4b4: Tffa657StringTb4b4b4,
Te6edf3nameTb4b4b4: Tffa657StringTb4b4b4,
Te6edf3messageTb4b4b4: Tffa657StringTb4b4b4,
Te6edf3isBroadcastTb4b4b4: Tffa657BooleanTb4b4b4,
Te6edf3channelNameTb4b4b4: Tffa657String?Tb4b4b4,
Te6edf3isSilentTb4b4b4: Tffa657BooleanTb4b4b4,
Tb4b4b4) Tb4b4b4{
Te6edf3showConversationNotificationTb4b4b4(Te6edf3contactKeyTb4b4b4, Te6edf3isBroadcastTb4b4b4, Te6edf3channelNameTb4b4b4, Te6edf3conversationName Tff7b72= Te6edf3nameTb4b4b4, Te6edf3isSilent Tff7b72= Te6edf3isSilentTb4b4b4)
Tb4b4b4}

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffupdateReactionNotificationTb4b4b4(
Te6edf3contactKeyTb4b4b4: Tffa657StringTb4b4b4,
Te6edf3nameTb4b4b4: Tffa657StringTb4b4b4,
Te6edf3emojiTb4b4b4: Tffa657StringTb4b4b4,
Te6edf3isBroadcastTb4b4b4: Tffa657BooleanTb4b4b4,
Te6edf3channelNameTb4b4b4: Tffa657String?Tb4b4b4,
Te6edf3isSilentTb4b4b4: Tffa657BooleanTb4b4b4,
Tb4b4b4) Tb4b4b4{
Te6edf3showConversationNotificationTb4b4b4(Te6edf3contactKeyTb4b4b4, Te6edf3isBroadcastTb4b4b4, Te6edf3channelNameTb4b4b4, Te6edf3conversationName Tff7b72= Te6edf3nameTb4b4b4, Te6edf3isSilent Tff7b72= Te6edf3isSilentTb4b4b4)
Tb4b4b4}

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffupdateWaypointNotificationTb4b4b4(
Te6edf3contactKeyTb4b4b4: Tffa657StringTb4b4b4,
Te6edf3nameTb4b4b4: Tffa657StringTb4b4b4,
Te6edf3messageTb4b4b4: Tffa657StringTb4b4b4,
Te6edf3waypointIdTb4b4b4: Tffa657IntTb4b4b4,
Te6edf3isSilentTb4b4b4: Tffa657BooleanTb4b4b4,
Tb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3notification Tff7b72= Te6edf3createWaypointNotificationTb4b4b4(Te6edf3nameTb4b4b4, Te6edf3messageTb4b4b4, Te6edf3waypointIdTb4b4b4, Te6edf3isSilentTb4b4b4)
Te6edf3notificationManagerTb4b4b4.Te6edf3notifyTb4b4b4(Te6edf3TAG_WAYPOINTTb4b4b4, Te6edf3contactKeyTb4b4b4.Te6edf3hashCodeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3notificationTb4b4b4)
Tb4b4b4}

Tff7b72private Tff7b72suspend Tff7b72fun Td2a8ffshowConversationNotificationTb4b4b4(
Te6edf3contactKeyTb4b4b4: Tffa657StringTb4b4b4,
Te6edf3isBroadcastTb4b4b4: Tffa657BooleanTb4b4b4,
Te6edf3channelNameTb4b4b4: Tffa657String?Tb4b4b4,
Te6edf3conversationNameTb4b4b4: Tffa657StringTb4b4b4,
Te6edf3isSilentTb4b4b4: Tffa657Boolean Tff7b72= Tff7b72falseTb4b4b4,
Tb4b4b4) Tb4b4b4{
T8b949e// Publish (or refresh) a long-lived conversation shortcut before the notification references it, so Android can
T8b949e// rank the notification in the shade's Conversations section and expose it to Android Auto/Wear. A channel name
T8b949e// labels a broadcast conversation; a direct message is labelled by the other participant's name.
T8b949e// Both names come from packet metadata and can be empty, so prefer the first non-blank one.
Te6edf3conversationShortcutPublisherTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3ensureConversationShortcutTb4b4b4(
Te6edf3contactKeyTb4b4b4,
Te6edf3channelNameTff7b72?.Te6edf3takeIf Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3isNotBlankTb4b4b4(Tb4b4b4) Tb4b4b4} Tff7b72?: Te6edf3conversationNameTb4b4b4,
Tb4b4b4)

Tff7b72val Te6edf3ourNode Tff7b72= Te6edf3nodeRepositoryTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3ourNodeInfoTb4b4b4.Te6edf3value
Tff7b72val Te6edf3history Tff7b72=
Te6edf3packetRepositoryTb4b4b4.Te6edf3value
Tb4b4b4.Te6edf3getMessagesFromTb4b4b4(Te6edf3contactKeyTb4b4b4, Te6edf3includeFiltered Tff7b72= Tff7b72falseTb4b4b4) Tb4b4b4{ Te6edf3nodeId Tff7b72-Tff7b72>
Tff7b72if Tb4b4b4(Te6edf3nodeId Tff7b72=Tff7b72= Te6edf3NodeAddressTb4b4b4.Te6edf3ID_LOCALTb4b4b4) Tb4b4b4{
Te6edf3ourNode Tff7b72?: Te6edf3nodeRepositoryTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3getNodeTb4b4b4(Te6edf3nodeIdTb4b4b4)
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3nodeRepositoryTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3getNodeTb4b4b4(Te6edf3nodeIdTb4b4b4.Te6edf3orEmptyTb4b4b4(Tb4b4b4)Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4.Te6edf3firstTb4b4b4(Tb4b4b4)

Tff7b72val Te6edf3unread Tff7b72= Te6edf3historyTb4b4b4.Te6edf3filter Tb4b4b4{ Tff7b72!Tffa657itTb4b4b4.Te6edf3read Tb4b4b4}
Tff7b72val Te6edf3displayHistory Tff7b72=
Tff7b72if Tb4b4b4(Te6edf3unreadTb4b4b4.Te6edf3size Tff7b72< Te6edf3MIN_CONTEXT_MESSAGESTb4b4b4) Tb4b4b4{
Te6edf3historyTb4b4b4.Te6edf3takeTb4b4b4(Te6edf3MIN_CONTEXT_MESSAGESTb4b4b4)Tb4b4b4.Te6edf3reversedTb4b4b4(Tb4b4b4)
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3unreadTb4b4b4.Te6edf3takeTb4b4b4(Te6edf3MAX_HISTORY_MESSAGESTb4b4b4)Tb4b4b4.Te6edf3reversedTb4b4b4(Tb4b4b4)
Tb4b4b4}

Tff7b72if Tb4b4b4(Te6edf3displayHistoryTb4b4b4.Te6edf3isEmptyTb4b4b4(Tb4b4b4)Tb4b4b4) Tff7b72return

Tff7b72val Te6edf3notification Tff7b72=
Te6edf3createConversationNotificationTb4b4b4(
Te6edf3contactKey Tff7b72= Te6edf3contactKeyTb4b4b4,
Te6edf3isBroadcast Tff7b72= Te6edf3isBroadcastTb4b4b4,
Te6edf3channelName Tff7b72= Te6edf3channelNameTb4b4b4,
Te6edf3history Tff7b72= Te6edf3displayHistoryTb4b4b4,
Te6edf3isSilent Tff7b72= Te6edf3isSilentTb4b4b4,
Tb4b4b4)
Te6edf3notificationManagerTb4b4b4.Te6edf3notifyTb4b4b4(Te6edf3TAG_MESSAGETb4b4b4, Te6edf3contactKeyTb4b4b4.Te6edf3hashCodeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3notificationTb4b4b4)
Te6edf3showGroupSummaryTb4b4b4(Tb4b4b4)
Tb4b4b4}

Tff7b72private Tff7b72suspend Tff7b72fun Td2a8ffshowGroupSummaryTb4b4b4(Te6edf3justCancelledIdTb4b4b4: Tffa657Int? Tff7b72= Tff7b72nullTb4b4b4) Tb4b4b4{
T8b949e// Exclude the summary itself by its group-summary flag rather than by id, so a conversation whose
T8b949e// contactKey.hashCode() happens to equal SUMMARY_ID is still counted as an active conversation.
T8b949e// Also exclude a conversation we just cancelled: activeNotifications does not reflect a cancel() issued
T8b949e// moments earlier, so without this the summary would be rebuilt from stale state and orphaned in the shade
T8b949e// (and Android Auto) after the last message is dismissed via reply / mark-as-read.
Tff7b72val Te6edf3activeNotifications Tff7b72=
Te6edf3notificationManagerTb4b4b4.Te6edf3activeNotificationsTb4b4b4.Te6edf3filter Tb4b4b4{
Tffa657itTb4b4b4.Te6edf3notificationTb4b4b4.Te6edf3group Tff7b72=Tff7b72= Te6edf3GROUP_KEY_MESSAGES Tff7b72&Tff7b72&
Tb4b4b4(Tffa657itTb4b4b4.Te6edf3notificationTb4b4b4.Te6edf3flags Te6edf3and Te6edf3NotificationTb4b4b4.Te6edf3FLAG_GROUP_SUMMARYTb4b4b4) Tff7b72=Tff7b72= T79c0ff0 Tff7b72&Tff7b72&
Tff7b72!Tb4b4b4(Tffa657itTb4b4b4.Te6edf3tag Tff7b72=Tff7b72= Te6edf3TAG_MESSAGE Tff7b72&Tff7b72& Tffa657itTb4b4b4.Te6edf3id Tff7b72=Tff7b72= Te6edf3justCancelledIdTb4b4b4)
Tb4b4b4}

T8b949e// No conversations left — drop the summary too, otherwise it lingers in Android Auto after the
T8b949e// last message notification is cancelled (e.g. on reply / mark-as-read).
Tff7b72if Tb4b4b4(Te6edf3activeNotificationsTb4b4b4.Te6edf3isEmptyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3notificationManagerTb4b4b4.Te6edf3cancelTb4b4b4(Te6edf3TAG_MESSAGE_SUMMARYTb4b4b4, Te6edf3SUMMARY_IDTb4b4b4)
Tff7b72return
Tb4b4b4}

Tff7b72val Te6edf3ourNode Tff7b72= Te6edf3nodeRepositoryTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3ourNodeInfoTb4b4b4.Te6edf3value
Tff7b72val Te6edf3meName Tff7b72= Te6edf3ourNodeTff7b72?.Te6edf3userTff7b72?.Te6edf3long_name Tff7b72?: Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3youTb4b4b4)
Tff7b72val Te6edf3me Tff7b72=
Te6edf3PersonTb4b4b4.Te6edf3BuilderTb4b4b4(Tb4b4b4)
Tb4b4b4.Te6edf3setNameTb4b4b4(Te6edf3meNameTb4b4b4)
Tb4b4b4.Te6edf3setKeyTb4b4b4(Te6edf3ourNodeTff7b72?.Te6edf3userTff7b72?.Te6edf3id Tff7b72?: Te6edf3NodeAddressTb4b4b4.Te6edf3ID_LOCALTb4b4b4)
Tb4b4b4.Te6edf3apply Tb4b4b4{
Te6edf3ourNodeTff7b72?.Te6edf3let Tb4b4b4{
Te6edf3setIconTb4b4b4(Te6edf3cachedPersonIconTb4b4b4(Tffa657itTb4b4b4.Te6edf3userTb4b4b4.Te6edf3idTb4b4b4, Tffa657itTb4b4b4.Te6edf3userTb4b4b4.Te6edf3short_nameTb4b4b4, Tffa657itTb4b4b4.Te6edf3colorsTb4b4b4.Te6edf3secondTb4b4b4, Tffa657itTb4b4b4.Te6edf3colorsTb4b4b4.Te6edf3firstTb4b4b4)Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4.Te6edf3buildTb4b4b4(Tb4b4b4)

Tff7b72val Te6edf3messagingStyle Tff7b72=
Te6edf3NotificationCompatTb4b4b4.Te6edf3MessagingStyleTb4b4b4(Te6edf3meTb4b4b4)
Tb4b4b4.Te6edf3setGroupConversationTb4b4b4(Tff7b72trueTb4b4b4)
Tb4b4b4.Te6edf3setConversationTitleTb4b4b4(Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3meshtastic_app_nameTb4b4b4)Tb4b4b4)

Te6edf3activeNotificationsTb4b4b4.Te6edf3forEach Tb4b4b4{ Te6edf3sbn Tff7b72-Tff7b72>
T8b949e// Prefer the child's real MessagingStyle: its latest message carries the actual sender (Person, icon) and
T8b949e// timestamp, so the summary line reads "Hawk Ridge: …" rather than the conversation title.
Tff7b72val Te6edf3latest Tff7b72=
Te6edf3NotificationCompatTb4b4b4.Te6edf3MessagingStyleTb4b4b4.Te6edf3extractMessagingStyleFromNotificationTb4b4b4(Te6edf3sbnTb4b4b4.Te6edf3notificationTb4b4b4)
Tff7b72?.Te6edf3messages
Tff7b72?.Te6edf3lastOrNullTb4b4b4(Tb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3latestTff7b72?.Te6edf3text Tff7b72!Tff7b72= Tff7b72nullTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3senderPerson Tff7b72= Te6edf3latestTb4b4b4.Te6edf3person Tff7b72?: Te6edf3PersonTb4b4b4.Te6edf3BuilderTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3setNameTb4b4b4(Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3youTb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3buildTb4b4b4(Tb4b4b4)
Te6edf3messagingStyleTb4b4b4.Te6edf3addMessageTb4b4b4(Te6edf3latestTb4b4b4.Te6edf3textTb4b4b4, Te6edf3latestTb4b4b4.Te6edf3timestampTb4b4b4, Te6edf3senderPersonTb4b4b4)
Tb4b4b4} Tff7b72else Tb4b4b4{
T8b949e// Fallback for children without an extractable style: rebuild a generic line from the extras.
Tff7b72val Te6edf3senderTitle Tff7b72= Te6edf3sbnTb4b4b4.Te6edf3notificationTb4b4b4.Te6edf3extrasTb4b4b4.Te6edf3getCharSequenceTb4b4b4(Te6edf3NotificationTb4b4b4.Te6edf3EXTRA_TITLETb4b4b4)
Tff7b72val Te6edf3messageText Tff7b72= Te6edf3sbnTb4b4b4.Te6edf3notificationTb4b4b4.Te6edf3extrasTb4b4b4.Te6edf3getCharSequenceTb4b4b4(Te6edf3NotificationTb4b4b4.Te6edf3EXTRA_TEXTTb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3senderTitle Tff7b72!Tff7b72= Tff7b72null Tff7b72&Tff7b72& Te6edf3messageText Tff7b72!Tff7b72= Tff7b72nullTb4b4b4) Tb4b4b4{
Te6edf3messagingStyleTb4b4b4.Te6edf3addMessageTb4b4b4(Te6edf3messageTextTb4b4b4, Te6edf3sbnTb4b4b4.Te6edf3postTimeTb4b4b4, Te6edf3PersonTb4b4b4.Te6edf3BuilderTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3setNameTb4b4b4(Te6edf3senderTitleTb4b4b4)Tb4b4b4.Te6edf3buildTb4b4b4(Tb4b4b4)Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4}

Tff7b72val Te6edf3summaryNotification Tff7b72=
Te6edf3commonBuilderTb4b4b4(Te6edf3NotificationTypeTb4b4b4.Te6edf3DirectMessageTb4b4b4)
Tb4b4b4.Te6edf3setSmallIconTb4b4b4(Te6edf3drawableTb4b4b4.Te6edf3meshtastic_ic_notificationTb4b4b4)
Tb4b4b4.Te6edf3setStyleTb4b4b4(Te6edf3messagingStyleTb4b4b4)
Tb4b4b4.Te6edf3setGroupTb4b4b4(Te6edf3GROUP_KEY_MESSAGESTb4b4b4)
Tb4b4b4.Te6edf3setGroupSummaryTb4b4b4(Tff7b72trueTb4b4b4)
T8b949e// Only the child conversation notifications alert; without this the summary (posted on a HIGH channel)
T8b949e// can buzz a second time for every message.
Tb4b4b4.Te6edf3setGroupAlertBehaviorTb4b4b4(Te6edf3NotificationCompatTb4b4b4.Te6edf3GROUP_ALERT_CHILDRENTb4b4b4)
Tb4b4b4.Te6edf3setAutoCancelTb4b4b4(Tff7b72trueTb4b4b4)
Tb4b4b4.Te6edf3buildTb4b4b4(Tb4b4b4)

Te6edf3notificationManagerTb4b4b4.Te6edf3notifyTb4b4b4(Te6edf3TAG_MESSAGE_SUMMARYTb4b4b4, Te6edf3SUMMARY_IDTb4b4b4, Te6edf3summaryNotificationTb4b4b4)
Tb4b4b4}

Tff7b72override Tff7b72fun Td2a8ffshowAlertNotificationTb4b4b4(Te6edf3contactKeyTb4b4b4: Tffa657StringTb4b4b4, Te6edf3nameTb4b4b4: Tffa657StringTb4b4b4, Te6edf3alertTb4b4b4: Tffa657StringTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3notification Tff7b72= Te6edf3createAlertNotificationTb4b4b4(Te6edf3contactKeyTb4b4b4, Te6edf3nameTb4b4b4, Te6edf3alertTb4b4b4)
T8b949e// Use a consistent, unique ID for each alert source.
Te6edf3notificationManagerTb4b4b4.Te6edf3notifyTb4b4b4(Te6edf3TAG_ALERTTb4b4b4, Te6edf3nameTb4b4b4.Te6edf3hashCodeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3notificationTb4b4b4)
Tb4b4b4}

Tff7b72override Tff7b72fun Td2a8ffshowNewNodeSeenNotificationTb4b4b4(Te6edf3nodeTb4b4b4: Te6edf3NodeTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3notification Tff7b72= Te6edf3createNewNodeSeenNotificationTb4b4b4(Te6edf3nodeTb4b4b4.Te6edf3userTb4b4b4.Te6edf3short_nameTb4b4b4, Te6edf3nodeTb4b4b4.Te6edf3userTb4b4b4.Te6edf3long_nameTb4b4b4, Te6edf3nodeTb4b4b4.Te6edf3numTb4b4b4)
Te6edf3notificationManagerTb4b4b4.Te6edf3notifyTb4b4b4(Te6edf3TAG_NEW_NODETb4b4b4, Te6edf3nodeTb4b4b4.Te6edf3numTb4b4b4, Te6edf3notificationTb4b4b4)
Tb4b4b4}

Tff7b72override Tff7b72fun Td2a8ffshowOrUpdateLowBatteryNotificationTb4b4b4(Te6edf3nodeTb4b4b4: Te6edf3NodeTb4b4b4, Te6edf3isRemoteTb4b4b4: Tffa657BooleanTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3notification Tff7b72= Te6edf3createLowBatteryNotificationTb4b4b4(Te6edf3nodeTb4b4b4, Te6edf3isRemoteTb4b4b4)
Te6edf3notificationManagerTb4b4b4.Te6edf3notifyTb4b4b4(Te6edf3TAG_LOW_BATTERYTb4b4b4, Te6edf3nodeTb4b4b4.Te6edf3numTb4b4b4, Te6edf3notificationTb4b4b4)
Tb4b4b4}

Tff7b72override Tff7b72fun Td2a8ffshowClientNotificationTb4b4b4(Te6edf3clientNotificationTb4b4b4: Te6edf3ClientNotificationTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3notification Tff7b72=
Te6edf3createClientNotificationTb4b4b4(Te6edf3getStringTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3client_notificationTb4b4b4)Tb4b4b4, Te6edf3clientNotificationTb4b4b4.Te6edf3messageTb4b4b4)
Te6edf3notificationManagerTb4b4b4.Te6edf3notifyTb4b4b4(Te6edf3TAG_CLIENTTb4b4b4, Te6edf3clientNotificationTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3hashCodeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3notificationTb4b4b4)
Tb4b4b4}

Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffcancelMessageNotificationTb4b4b4(Te6edf3contactKeyTb4b4b4: Tffa657StringTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3id Tff7b72= Te6edf3contactKeyTb4b4b4.Te6edf3hashCodeTb4b4b4(Tb4b4b4)
Te6edf3notificationManagerTb4b4b4.Te6edf3cancelTb4b4b4(Te6edf3TAG_MESSAGETb4b4b4, Te6edf3idTb4b4b4)
T8b949e// Rebuild (or clear) the group summary so it doesn't keep showing the dismissed conversation in Android Auto.
T8b949e// Pass the id we just cancelled so a stale activeNotifications snapshot doesn't keep the summary alive.
Te6edf3showGroupSummaryTb4b4b4(Te6edf3justCancelledId Tff7b72= Te6edf3idTb4b4b4)
Tb4b4b4}

T8b949e/**
* Re-posts the conversation silently after an inline reply, so the notification updates in place with the sent
* reply appended (the read context becomes historic, the reply is the visible latest message) instead of
* disappearing. Re-posting under the same (tag, id) is also what resolves the RemoteInput spinner.
*/
Tff7b72override Tff7b72suspend Tff7b72fun Td2a8ffrefreshConversationAfterReplyTb4b4b4(Te6edf3contactKeyTb4b4b4: Tffa657StringTb4b4b4) Tb4b4b4{
Tff7b72val Te6edf3isBroadcast Tff7b72= Te6edf3contactKeyTb4b4b4.Te6edf3containsTb4b4b4(Te6edf3NodeAddressTb4b4b4.Te6edf3ID_BROADCASTTb4b4b4)
Tff7b72val Te6edf3conversationNameTb4b4b4: Tffa657String
Tff7b72var Te6edf3channelNameTb4b4b4: Tffa657String? Tff7b72= Tff7b72null
Tff7b72if Tb4b4b4(Te6edf3isBroadcastTb4b4b4) Tb4b4b4{
T8b949e// Resolve the effective channel name (an empty primary shows its modem-preset name, e.g. "LongFast").
Tff7b72val Te6edf3channelSet Tff7b72= Te6edf3radioConfigRepositoryTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3channelSetFlowTb4b4b4.Te6edf3firstTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3lora Tff7b72= Te6edf3channelSetTb4b4b4.Te6edf3lora_config Tff7b72?: Te6edf3ChannelTb4b4b4.Te6edf3defaultTb4b4b4.Te6edf3loraConfig
Tff7b72val Te6edf3index Tff7b72= Te6edf3contactKeyTb4b4b4.Te6edf3substringBeforeTb4b4b4(Te6edf3NodeAddressTb4b4b4.Te6edf3ID_BROADCASTTb4b4b4)Tb4b4b4.Te6edf3toIntOrNullTb4b4b4(Tb4b4b4)
Te6edf3channelName Tff7b72= Te6edf3indexTff7b72?.Te6edf3let Tb4b4b4{ Te6edf3channelSetTb4b4b4.Te6edf3settingsTb4b4b4.Te6edf3getOrNullTb4b4b4(Tffa657itTb4b4b4) Tb4b4b4}Tff7b72?.Te6edf3let Tb4b4b4{ Te6edf3ChannelTb4b4b4(Tffa657itTb4b4b4, Te6edf3loraTb4b4b4)Tb4b4b4.Te6edf3name Tb4b4b4}
T8b949e// Never fall back to the raw contactKey for user-facing labels (privacy-first convention).
Te6edf3conversationName Tff7b72= Te6edf3channelName Tff7b72?: Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3channelTb4b4b4)
Tb4b4b4} Tff7b72else Tb4b4b4{
T8b949e// DM contactKey is "<channelIndex><userId>" where userId starts at the '!'.
Tff7b72val Te6edf3userId Tff7b72= Ta5d6ff"Ta5d6ff!Ta5d6ff" Tff7b72+ Te6edf3contactKeyTb4b4b4.Te6edf3substringAfterTb4b4b4(Ta5d6ff"Ta5d6ff!Ta5d6ff"Tb4b4b4, Te6edf3missingDelimiterValue Tff7b72= Ta5d6ff"Ta5d6ff"Tb4b4b4)
Tff7b72val Te6edf3peer Tff7b72= Te6edf3nodeRepositoryTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3nodeDBbyNumTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3valuesTb4b4b4.Te6edf3find Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3userTb4b4b4.Te6edf3id Tff7b72=Tff7b72= Te6edf3userId Tb4b4b4}
Te6edf3conversationName Tff7b72=
Te6edf3peerTff7b72?.Te6edf3userTff7b72?.Te6edf3long_nameTff7b72?.Te6edf3takeIf Tb4b4b4{ Tffa657itTb4b4b4.Te6edf3isNotBlankTb4b4b4(Tb4b4b4) Tb4b4b4} Tff7b72?: Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3unknown_usernameTb4b4b4)
Tb4b4b4}
Te6edf3showConversationNotificationTb4b4b4(Te6edf3contactKeyTb4b4b4, Te6edf3isBroadcastTb4b4b4, Te6edf3channelNameTb4b4b4, Te6edf3conversationNameTb4b4b4, Te6edf3isSilent Tff7b72= Tff7b72trueTb4b4b4)
Tb4b4b4}

Tff7b72override Tff7b72fun Td2a8ffcancelLowBatteryNotificationTb4b4b4(Te6edf3nodeTb4b4b4: Te6edf3NodeTb4b4b4) Tff7b72= Te6edf3notificationManagerTb4b4b4.Te6edf3cancelTb4b4b4(Te6edf3TAG_LOW_BATTERYTb4b4b4, Te6edf3nodeTb4b4b4.Te6edf3numTb4b4b4)

Tff7b72override Tff7b72fun Td2a8ffclearClientNotificationTb4b4b4(Te6edf3notificationTb4b4b4: Te6edf3ClientNotificationTb4b4b4) Tff7b72=
Te6edf3notificationManagerTb4b4b4.Te6edf3cancelTb4b4b4(Te6edf3TAG_CLIENTTb4b4b4, Te6edf3notificationTb4b4b4.Te6edf3toStringTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3hashCodeTb4b4b4(Tb4b4b4)Tb4b4b4)

T8b949e// endregion

T8b949e// region Notification Creation
Tff7b72private Tff7b72fun Td2a8ffcreateServiceStateNotificationTb4b4b4(Te6edf3nameTb4b4b4: Tffa657StringTb4b4b4, Te6edf3messageTb4b4b4: Tffa657String?Tb4b4b4, Te6edf3nextUpdateAtTb4b4b4: Tffa657Long?Tb4b4b4)Tb4b4b4: Te6edf3Notification Tb4b4b4{
Tff7b72val Te6edf3builder Tff7b72=
Te6edf3commonBuilderTb4b4b4(Te6edf3NotificationTypeTb4b4b4.Te6edf3ServiceStateTb4b4b4)
Tb4b4b4.Te6edf3setPriorityTb4b4b4(Te6edf3NotificationCompatTb4b4b4.Te6edf3PRIORITY_MINTb4b4b4)
Tb4b4b4.Te6edf3setCategoryTb4b4b4(Te6edf3NotificationTb4b4b4.Te6edf3CATEGORY_SERVICETb4b4b4)
Tb4b4b4.Te6edf3setOngoingTb4b4b4(Tff7b72trueTb4b4b4)
T8b949e// Android 12+ may defer FGS notifications ~10s; show immediately so the user watching a
T8b949e// "Connecting…" state gets feedback right away.
Tb4b4b4.Te6edf3setForegroundServiceBehaviorTb4b4b4(Te6edf3NotificationCompatTb4b4b4.Te6edf3FOREGROUND_SERVICE_IMMEDIATETb4b4b4)
Tb4b4b4.Te6edf3setContentTitleTb4b4b4(Te6edf3nameTb4b4b4)
Tb4b4b4.Te6edf3setShowWhenTb4b4b4(Tff7b72trueTb4b4b4)

Te6edf3messageTff7b72?.Te6edf3let Tb4b4b4{
T8b949e// First line of message is used for collapsed view, ensure it doesn't have a bullet
Te6edf3builderTb4b4b4.Te6edf3setContentTextTb4b4b4(Tffa657itTb4b4b4.Te6edf3substringBeforeTb4b4b4(Ta5d6ff"Ta5d6ff\Ta5d6ffnTa5d6ff"Tb4b4b4)Tb4b4b4.Te6edf3removePrefixTb4b4b4(Te6edf3BULLETTb4b4b4)Tb4b4b4)
Te6edf3builderTb4b4b4.Te6edf3setStyleTb4b4b4(Te6edf3NotificationCompatTb4b4b4.Te6edf3BigTextStyleTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3bigTextTb4b4b4(Tffa657itTb4b4b4)Tb4b4b4)
Tb4b4b4}

Te6edf3nextUpdateAt
Tff7b72?.Te6edf3takeIf Tb4b4b4{ Tffa657it Tff7b72> Te6edf3nowMillis Tb4b4b4}
Tff7b72?.Te6edf3let Tb4b4b4{
Te6edf3builderTb4b4b4.Te6edf3setWhenTb4b4b4(Tffa657itTb4b4b4)
Te6edf3builderTb4b4b4.Te6edf3setUsesChronometerTb4b4b4(Tff7b72trueTb4b4b4)
Te6edf3builderTb4b4b4.Te6edf3setChronometerCountDownTb4b4b4(Tff7b72trueTb4b4b4)
Tb4b4b4}

Tff7b72return Te6edf3builderTb4b4b4.Te6edf3buildTb4b4b4(Tb4b4b4)
Tb4b4b4}

Tf0883e@SuppressTb4b4b4(Ta5d6ff"Ta5d6ffLongMethodTa5d6ff"Tb4b4b4)
Tff7b72private Tff7b72suspend Tff7b72fun Td2a8ffcreateConversationNotificationTb4b4b4(
Te6edf3contactKeyTb4b4b4: Tffa657StringTb4b4b4,
Te6edf3isBroadcastTb4b4b4: Tffa657BooleanTb4b4b4,
Te6edf3channelNameTb4b4b4: Tffa657String?Tb4b4b4,
Te6edf3historyTb4b4b4: Te6edf3ListTff7b72<Te6edf3MessageTff7b72>Tb4b4b4,
Te6edf3isSilentTb4b4b4: Tffa657Boolean Tff7b72= Tff7b72falseTb4b4b4,
Tb4b4b4)Tb4b4b4: Te6edf3Notification Tb4b4b4{
Tff7b72val Te6edf3type Tff7b72= Tff7b72if Tb4b4b4(Te6edf3isBroadcastTb4b4b4) Te6edf3NotificationTypeTb4b4b4.Te6edf3BroadcastMessage Tff7b72else Te6edf3NotificationTypeTb4b4b4.Te6edf3DirectMessage
Tff7b72val Te6edf3builder Tff7b72= Te6edf3commonBuilderTb4b4b4(Te6edf3typeTb4b4b4, Te6edf3createOpenMessageIntentTb4b4b4(Te6edf3contactKeyTb4b4b4)Tb4b4b4)

Tff7b72if Tb4b4b4(Te6edf3isSilentTb4b4b4) Tb4b4b4{
Te6edf3builderTb4b4b4.Te6edf3setSilentTb4b4b4(Tff7b72trueTb4b4b4)
Tb4b4b4}

Tff7b72val Te6edf3ourNode Tff7b72= Te6edf3nodeRepositoryTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3ourNodeInfoTb4b4b4.Te6edf3value
Tff7b72val Te6edf3meName Tff7b72= Te6edf3ourNodeTff7b72?.Te6edf3userTff7b72?.Te6edf3long_name Tff7b72?: Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3youTb4b4b4)
Tff7b72val Te6edf3me Tff7b72=
Te6edf3PersonTb4b4b4.Te6edf3BuilderTb4b4b4(Tb4b4b4)
Tb4b4b4.Te6edf3setNameTb4b4b4(Te6edf3meNameTb4b4b4)
Tb4b4b4.Te6edf3setKeyTb4b4b4(Te6edf3ourNodeTff7b72?.Te6edf3userTff7b72?.Te6edf3id Tff7b72?: Te6edf3NodeAddressTb4b4b4.Te6edf3ID_LOCALTb4b4b4)
Tb4b4b4.Te6edf3apply Tb4b4b4{
Te6edf3ourNodeTff7b72?.Te6edf3let Tb4b4b4{
Te6edf3setIconTb4b4b4(Te6edf3cachedPersonIconTb4b4b4(Tffa657itTb4b4b4.Te6edf3userTb4b4b4.Te6edf3idTb4b4b4, Tffa657itTb4b4b4.Te6edf3userTb4b4b4.Te6edf3short_nameTb4b4b4, Tffa657itTb4b4b4.Te6edf3colorsTb4b4b4.Te6edf3secondTb4b4b4, Tffa657itTb4b4b4.Te6edf3colorsTb4b4b4.Te6edf3firstTb4b4b4)Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tb4b4b4.Te6edf3buildTb4b4b4(Tb4b4b4)

Tff7b72val Te6edf3style Tff7b72=
Te6edf3NotificationCompatTb4b4b4.Te6edf3MessagingStyleTb4b4b4(Te6edf3meTb4b4b4)
Tb4b4b4.Te6edf3setGroupConversationTb4b4b4(Te6edf3channelName Tff7b72!Tff7b72= Tff7b72nullTb4b4b4)
Tb4b4b4.Te6edf3setConversationTitleTb4b4b4(Te6edf3channelNameTb4b4b4)

T8b949e// Already-read messages are added as *historic* context rather than as new content: MessagingStyle keeps them
T8b949e// available to accessibility services and Android Auto/Wear for conversation context without re-presenting them
T8b949e// as freshly-arrived messages. Unread messages (and reactions, which are themselves new events) are the actual
T8b949e// alerting content. When every message in the window is read (e.g. a reaction arrived on a read message) the
T8b949e// most recent one is kept as a normal message so the notification still has alerting content to show.
Tff7b72val Te6edf3anyUnread Tff7b72= Te6edf3historyTb4b4b4.Te6edf3any Tb4b4b4{ Tff7b72!Tffa657itTb4b4b4.Te6edf3read Tb4b4b4}
Tff7b72val Te6edf3lastIndex Tff7b72= Te6edf3historyTb4b4b4.Te6edf3lastIndex
Te6edf3historyTb4b4b4.Te6edf3forEachIndexed Tb4b4b4{ Te6edf3indexTb4b4b4, Te6edf3msg Tff7b72-Tff7b72>
T8b949e// Use the node attached to the message directly to ensure correct identification
Tff7b72val Te6edf3person Tff7b72=
Te6edf3PersonTb4b4b4.Te6edf3BuilderTb4b4b4(Tb4b4b4)
Tb4b4b4.Te6edf3setNameTb4b4b4(Te6edf3msgTb4b4b4.Te6edf3nodeTb4b4b4.Te6edf3userTb4b4b4.Te6edf3long_nameTb4b4b4)
Tb4b4b4.Te6edf3setKeyTb4b4b4(Te6edf3msgTb4b4b4.Te6edf3nodeTb4b4b4.Te6edf3userTb4b4b4.Te6edf3idTb4b4b4)
T8b949e// Favorite nodes feed the system's conversation-priority ranking (shade ordering, suggestions).
Tb4b4b4.Te6edf3setImportantTb4b4b4(Te6edf3msgTb4b4b4.Te6edf3nodeTb4b4b4.Te6edf3isFavoriteTb4b4b4)
Tb4b4b4.Te6edf3setIconTb4b4b4(
Te6edf3cachedPersonIconTb4b4b4(
Te6edf3msgTb4b4b4.Te6edf3nodeTb4b4b4.Te6edf3userTb4b4b4.Te6edf3idTb4b4b4,
Te6edf3msgTb4b4b4.Te6edf3nodeTb4b4b4.Te6edf3userTb4b4b4.Te6edf3short_nameTb4b4b4,
Te6edf3msgTb4b4b4.Te6edf3nodeTb4b4b4.Te6edf3colorsTb4b4b4.Te6edf3secondTb4b4b4,
Te6edf3msgTb4b4b4.Te6edf3nodeTb4b4b4.Te6edf3colorsTb4b4b4.Te6edf3firstTb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tb4b4b4.Te6edf3buildTb4b4b4(Tb4b4b4)

Tff7b72val Te6edf3text Tff7b72=
Te6edf3msgTb4b4b4.Te6edf3originalMessageTff7b72?.Te6edf3let Tb4b4b4{ Te6edf3original Tff7b72-Tff7b72>
Ta5d6ff"Ta5d6ff↩️ Ta5d6ff\"Tffd700${Te6edf3originalTb4b4b4.Te6edf3nodeTb4b4b4.Te6edf3userTb4b4b4.Te6edf3short_nameTffd700}Ta5d6ff: Tffd700${Te6edf3originalTb4b4b4.Te6edf3textTb4b4b4.Te6edf3takeTb4b4b4(Te6edf3SNIPPET_LENGTHTb4b4b4)Tffd700}Ta5d6ff...Ta5d6ff\"Ta5d6ff: Tffd700${Te6edf3msgTb4b4b4.Te6edf3textTffd700}Ta5d6ff"
Tb4b4b4} Tff7b72?: Te6edf3msgTb4b4b4.Te6edf3text

Tff7b72if Tb4b4b4(Te6edf3msgTb4b4b4.Te6edf3read Tff7b72&Tff7b72& Tb4b4b4(Te6edf3anyUnread Tff7b72|Tff7b72| Te6edf3index Tff7b72!Tff7b72= Te6edf3lastIndexTb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3styleTb4b4b4.Te6edf3addHistoricMessageTb4b4b4(Te6edf3NotificationCompatTb4b4b4.Te6edf3MessagingStyleTb4b4b4.Te6edf3MessageTb4b4b4(Te6edf3textTb4b4b4, Te6edf3msgTb4b4b4.Te6edf3receivedTimeTb4b4b4, Te6edf3personTb4b4b4)Tb4b4b4)
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3styleTb4b4b4.Te6edf3addMessageTb4b4b4(Te6edf3textTb4b4b4, Te6edf3msgTb4b4b4.Te6edf3receivedTimeTb4b4b4, Te6edf3personTb4b4b4)
Tb4b4b4}

T8b949e// Add reactions as separate "messages" in history if they exist
Te6edf3msgTb4b4b4.Te6edf3emojisTb4b4b4.Te6edf3forEach Tb4b4b4{ Te6edf3reaction Tff7b72-Tff7b72>
Tff7b72val Te6edf3reactorNode Tff7b72= Te6edf3nodeRepositoryTb4b4b4.Te6edf3valueTb4b4b4.Te6edf3getNodeTb4b4b4(Te6edf3reactionTb4b4b4.Te6edf3userTb4b4b4.Te6edf3idTb4b4b4)
Tff7b72val Te6edf3reactor Tff7b72=
Te6edf3PersonTb4b4b4.Te6edf3BuilderTb4b4b4(Tb4b4b4)
Tb4b4b4.Te6edf3setNameTb4b4b4(Te6edf3reactionTb4b4b4.Te6edf3userTb4b4b4.Te6edf3long_nameTb4b4b4)
Tb4b4b4.Te6edf3setKeyTb4b4b4(Te6edf3reactionTb4b4b4.Te6edf3userTb4b4b4.Te6edf3idTb4b4b4)
Tb4b4b4.Te6edf3setIconTb4b4b4(
Te6edf3cachedPersonIconTb4b4b4(
Te6edf3reactionTb4b4b4.Te6edf3userTb4b4b4.Te6edf3idTb4b4b4,
Te6edf3reactionTb4b4b4.Te6edf3userTb4b4b4.Te6edf3short_nameTb4b4b4,
Te6edf3reactorNodeTb4b4b4.Te6edf3colorsTb4b4b4.Te6edf3secondTb4b4b4,
Te6edf3reactorNodeTb4b4b4.Te6edf3colorsTb4b4b4.Te6edf3firstTb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tb4b4b4.Te6edf3buildTb4b4b4(Tb4b4b4)
Te6edf3styleTb4b4b4.Te6edf3addMessageTb4b4b4(
Ta5d6ff"Tffd700${Te6edf3reactionTb4b4b4.Te6edf3emojiTffd700}Ta5d6ff to Ta5d6ff\"Tffd700${Te6edf3msgTb4b4b4.Te6edf3textTb4b4b4.Te6edf3takeTb4b4b4(Te6edf3SNIPPET_LENGTHTb4b4b4)Tffd700}Ta5d6ff...Ta5d6ff\"Ta5d6ff"Tb4b4b4,
Te6edf3reactionTb4b4b4.Te6edf3timestampTb4b4b4,
Te6edf3reactorTb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Tff7b72val Te6edf3lastMessage Tff7b72= Te6edf3historyTb4b4b4.Te6edf3lastTb4b4b4(Tb4b4b4)

Te6edf3builder
Tb4b4b4.Te6edf3setCategoryTb4b4b4(Te6edf3NotificationTb4b4b4.Te6edf3CATEGORY_MESSAGETb4b4b4)
T8b949e// Link to the conversation shortcut so this is treated as a Conversation notification (Android 11+).
Tb4b4b4.Te6edf3setShortcutIdTb4b4b4(Te6edf3contactKeyTb4b4b4)
Tb4b4b4.Te6edf3setLocusIdTb4b4b4(Te6edf3LocusIdCompatTb4b4b4(Te6edf3contactKeyTb4b4b4)Tb4b4b4)
Tb4b4b4.Te6edf3setAutoCancelTb4b4b4(Tff7b72trueTb4b4b4)
Tb4b4b4.Te6edf3setStyleTb4b4b4(Te6edf3styleTb4b4b4)
Tb4b4b4.Te6edf3setGroupTb4b4b4(Te6edf3GROUP_KEY_MESSAGESTb4b4b4)
Tb4b4b4.Te6edf3setVisibilityTb4b4b4(Te6edf3NotificationCompatTb4b4b4.Te6edf3VISIBILITY_PRIVATETb4b4b4)
Tb4b4b4.Te6edf3setWhenTb4b4b4(Te6edf3lastMessageTb4b4b4.Te6edf3receivedTimeTb4b4b4)
Tb4b4b4.Te6edf3setShowWhenTb4b4b4(Tff7b72trueTb4b4b4)
Tb4b4b4.Te6edf3addActionTb4b4b4(Te6edf3createReplyActionTb4b4b4(Te6edf3contactKeyTb4b4b4)Tb4b4b4)
Tb4b4b4.Te6edf3addActionTb4b4b4(Te6edf3createMarkAsReadActionTb4b4b4(Te6edf3contactKeyTb4b4b4)Tb4b4b4)
Tb4b4b4.Te6edf3addActionTb4b4b4(
Te6edf3createReactionActionTb4b4b4(
Te6edf3contactKey Tff7b72= Te6edf3contactKeyTb4b4b4,
Te6edf3packetId Tff7b72= Te6edf3lastMessageTb4b4b4.Te6edf3packetIdTb4b4b4,
Te6edf3toId Tff7b72= Te6edf3lastMessageTb4b4b4.Te6edf3nodeTb4b4b4.Te6edf3userTb4b4b4.Te6edf3idTb4b4b4,
Te6edf3channelIndex Tff7b72= Te6edf3lastMessageTb4b4b4.Te6edf3nodeTb4b4b4.Te6edf3channelTb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)

Tff7b72return Te6edf3builderTb4b4b4.Te6edf3buildTb4b4b4(Tb4b4b4)
Tb4b4b4}

Tff7b72private Tff7b72fun Td2a8ffcreateWaypointNotificationTb4b4b4(
Te6edf3nameTb4b4b4: Tffa657StringTb4b4b4,
Te6edf3messageTb4b4b4: Tffa657StringTb4b4b4,
Te6edf3waypointIdTb4b4b4: Tffa657IntTb4b4b4,
Te6edf3isSilentTb4b4b4: Tffa657BooleanTb4b4b4,
Tb4b4b4)Tb4b4b4: Te6edf3Notification Tb4b4b4{
Tff7b72val Te6edf3person Tff7b72= Te6edf3PersonTb4b4b4.Te6edf3BuilderTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3setNameTb4b4b4(Te6edf3nameTb4b4b4)Tb4b4b4.Te6edf3buildTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3style Tff7b72= Te6edf3NotificationCompatTb4b4b4.Te6edf3MessagingStyleTb4b4b4(Te6edf3personTb4b4b4)Tb4b4b4.Te6edf3addMessageTb4b4b4(Te6edf3messageTb4b4b4, Te6edf3nowMillisTb4b4b4, Te6edf3personTb4b4b4)

Tff7b72val Te6edf3builder Tff7b72=
Te6edf3commonBuilderTb4b4b4(Te6edf3NotificationTypeTb4b4b4.Te6edf3WaypointTb4b4b4, Te6edf3createOpenWaypointIntentTb4b4b4(Te6edf3waypointIdTb4b4b4)Tb4b4b4)
Tb4b4b4.Te6edf3setCategoryTb4b4b4(Te6edf3NotificationTb4b4b4.Te6edf3CATEGORY_MESSAGETb4b4b4)
Tb4b4b4.Te6edf3setAutoCancelTb4b4b4(Tff7b72trueTb4b4b4)
Tb4b4b4.Te6edf3setStyleTb4b4b4(Te6edf3styleTb4b4b4)
Tb4b4b4.Te6edf3setGroupTb4b4b4(Te6edf3GROUP_KEY_MESSAGESTb4b4b4)
Tb4b4b4.Te6edf3setVisibilityTb4b4b4(Te6edf3NotificationCompatTb4b4b4.Te6edf3VISIBILITY_PRIVATETb4b4b4)
Tb4b4b4.Te6edf3setWhenTb4b4b4(Te6edf3nowMillisTb4b4b4)
Tb4b4b4.Te6edf3setShowWhenTb4b4b4(Tff7b72trueTb4b4b4)

Tff7b72if Tb4b4b4(Te6edf3isSilentTb4b4b4) Tb4b4b4{
Te6edf3builderTb4b4b4.Te6edf3setSilentTb4b4b4(Tff7b72trueTb4b4b4)
Tb4b4b4}

Tff7b72return Te6edf3builderTb4b4b4.Te6edf3buildTb4b4b4(Tb4b4b4)
Tb4b4b4}

Tff7b72private Tff7b72fun Td2a8ffcreateAlertNotificationTb4b4b4(Te6edf3contactKeyTb4b4b4: Tffa657StringTb4b4b4, Te6edf3nameTb4b4b4: Tffa657StringTb4b4b4, Te6edf3alertTb4b4b4: Tffa657StringTb4b4b4)Tb4b4b4: Te6edf3Notification Tb4b4b4{
Tff7b72val Te6edf3person Tff7b72= Te6edf3PersonTb4b4b4.Te6edf3BuilderTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3setNameTb4b4b4(Te6edf3nameTb4b4b4)Tb4b4b4.Te6edf3buildTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3style Tff7b72= Te6edf3NotificationCompatTb4b4b4.Te6edf3MessagingStyleTb4b4b4(Te6edf3personTb4b4b4)Tb4b4b4.Te6edf3addMessageTb4b4b4(Te6edf3alertTb4b4b4, Te6edf3nowMillisTb4b4b4, Te6edf3personTb4b4b4)

Tff7b72return Te6edf3commonBuilderTb4b4b4(Te6edf3NotificationTypeTb4b4b4.Te6edf3AlertTb4b4b4, Te6edf3createOpenMessageIntentTb4b4b4(Te6edf3contactKeyTb4b4b4)Tb4b4b4)
Tb4b4b4.Te6edf3setPriorityTb4b4b4(Te6edf3NotificationCompatTb4b4b4.Te6edf3PRIORITY_HIGHTb4b4b4)
Tb4b4b4.Te6edf3setCategoryTb4b4b4(Te6edf3NotificationTb4b4b4.Te6edf3CATEGORY_ALARMTb4b4b4)
Tb4b4b4.Te6edf3setAutoCancelTb4b4b4(Tff7b72trueTb4b4b4)
Tb4b4b4.Te6edf3setStyleTb4b4b4(Te6edf3styleTb4b4b4)
Tb4b4b4.Te6edf3buildTb4b4b4(Tb4b4b4)
Tb4b4b4}

Tff7b72private Tff7b72fun Td2a8ffcreateNewNodeSeenNotificationTb4b4b4(Te6edf3nameTb4b4b4: Tffa657StringTb4b4b4, Te6edf3messageTb4b4b4: Tffa657StringTb4b4b4, Te6edf3nodeNumTb4b4b4: Tffa657IntTb4b4b4)Tb4b4b4: Te6edf3Notification Tb4b4b4{
Tff7b72val Te6edf3title Tff7b72= Te6edf3getStringTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3new_node_seenTb4b4b4, Te6edf3nameTb4b4b4)
Tff7b72val Te6edf3builder Tff7b72=
Te6edf3commonBuilderTb4b4b4(Te6edf3NotificationTypeTb4b4b4.Te6edf3NewNodeTb4b4b4, Te6edf3createOpenNodeDetailIntentTb4b4b4(Te6edf3nodeNumTb4b4b4)Tb4b4b4)
Tb4b4b4.Te6edf3setCategoryTb4b4b4(Te6edf3NotificationTb4b4b4.Te6edf3CATEGORY_STATUSTb4b4b4)
Tb4b4b4.Te6edf3setAutoCancelTb4b4b4(Tff7b72trueTb4b4b4)
Tb4b4b4.Te6edf3setContentTitleTb4b4b4(Te6edf3titleTb4b4b4)
Tb4b4b4.Te6edf3setWhenTb4b4b4(Te6edf3nowMillisTb4b4b4)
Tb4b4b4.Te6edf3setShowWhenTb4b4b4(Tff7b72trueTb4b4b4)
Tb4b4b4.Te6edf3setContentTextTb4b4b4(Te6edf3messageTb4b4b4)
Tb4b4b4.Te6edf3setStyleTb4b4b4(Te6edf3NotificationCompatTb4b4b4.Te6edf3BigTextStyleTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3bigTextTb4b4b4(Te6edf3messageTb4b4b4)Tb4b4b4)

Tff7b72return Te6edf3builderTb4b4b4.Te6edf3buildTb4b4b4(Tb4b4b4)
Tb4b4b4}

Tff7b72private Tff7b72fun Td2a8ffcreateLowBatteryNotificationTb4b4b4(Te6edf3nodeTb4b4b4: Te6edf3NodeTb4b4b4, Te6edf3isRemoteTb4b4b4: Tffa657BooleanTb4b4b4)Tb4b4b4: Te6edf3Notification Tb4b4b4{
Tff7b72val Te6edf3type Tff7b72= Tff7b72if Tb4b4b4(Te6edf3isRemoteTb4b4b4) Te6edf3NotificationTypeTb4b4b4.Te6edf3LowBatteryRemote Tff7b72else Te6edf3NotificationTypeTb4b4b4.Te6edf3LowBatteryLocal
Tff7b72val Te6edf3title Tff7b72= Te6edf3getStringTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3low_battery_titleTb4b4b4, Te6edf3nodeTb4b4b4.Te6edf3userTb4b4b4.Te6edf3short_nameTb4b4b4)
Tff7b72val Te6edf3batteryLevel Tff7b72= Te6edf3nodeTb4b4b4.Te6edf3deviceMetricsTb4b4b4.Te6edf3battery_level Tff7b72?: T79c0ff0
Tff7b72val Te6edf3message Tff7b72= Te6edf3getStringTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3low_battery_messageTb4b4b4, Te6edf3nodeTb4b4b4.Te6edf3userTb4b4b4.Te6edf3long_nameTb4b4b4, Te6edf3batteryLevelTb4b4b4)

Tff7b72return Te6edf3commonBuilderTb4b4b4(Te6edf3typeTb4b4b4, Te6edf3createOpenNodeDetailIntentTb4b4b4(Te6edf3nodeTb4b4b4.Te6edf3numTb4b4b4)Tb4b4b4)
Tb4b4b4.Te6edf3setCategoryTb4b4b4(Te6edf3NotificationTb4b4b4.Te6edf3CATEGORY_STATUSTb4b4b4)
Tb4b4b4.Te6edf3setOngoingTb4b4b4(Tff7b72trueTb4b4b4)
Tb4b4b4.Te6edf3setOnlyAlertOnceTb4b4b4(Tff7b72trueTb4b4b4)
Tb4b4b4.Te6edf3setProgressTb4b4b4(Te6edf3MAX_BATTERY_LEVELTb4b4b4, Te6edf3batteryLevelTb4b4b4, Tff7b72falseTb4b4b4)
Tb4b4b4.Te6edf3setContentTitleTb4b4b4(Te6edf3titleTb4b4b4)
Tb4b4b4.Te6edf3setContentTextTb4b4b4(Te6edf3messageTb4b4b4)
Tb4b4b4.Te6edf3setStyleTb4b4b4(Te6edf3NotificationCompatTb4b4b4.Te6edf3BigTextStyleTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3bigTextTb4b4b4(Te6edf3messageTb4b4b4)Tb4b4b4)
Tb4b4b4.Te6edf3setWhenTb4b4b4(Te6edf3nowMillisTb4b4b4)
Tb4b4b4.Te6edf3setShowWhenTb4b4b4(Tff7b72trueTb4b4b4)
Tb4b4b4.Te6edf3buildTb4b4b4(Tb4b4b4)
Tb4b4b4}

Tff7b72private Tff7b72fun Td2a8ffcreateClientNotificationTb4b4b4(Te6edf3nameTb4b4b4: Tffa657StringTb4b4b4, Te6edf3messageTb4b4b4: Tffa657StringTb4b4b4)Tb4b4b4: Te6edf3Notification Tff7b72=
Te6edf3commonBuilderTb4b4b4(Te6edf3NotificationTypeTb4b4b4.Te6edf3ClientTb4b4b4)
Tb4b4b4.Te6edf3setCategoryTb4b4b4(Te6edf3NotificationTb4b4b4.Te6edf3CATEGORY_ERRORTb4b4b4)
Tb4b4b4.Te6edf3setAutoCancelTb4b4b4(Tff7b72trueTb4b4b4)
Tb4b4b4.Te6edf3setContentTitleTb4b4b4(Te6edf3nameTb4b4b4)
Tb4b4b4.Te6edf3setContentTextTb4b4b4(Te6edf3messageTb4b4b4)
Tb4b4b4.Te6edf3setStyleTb4b4b4(Te6edf3NotificationCompatTb4b4b4.Te6edf3BigTextStyleTb4b4b4(Tb4b4b4)Tb4b4b4.Te6edf3bigTextTb4b4b4(Te6edf3messageTb4b4b4)Tb4b4b4)
Tb4b4b4.Te6edf3buildTb4b4b4(Tb4b4b4)

T8b949e// endregion

T8b949e// region Helper/Builder Methods
Tff7b72private Tff7b72val Te6edf3openAppIntentTb4b4b4: Te6edf3PendingIntent Tff7b72by Te6edf3lazy Tb4b4b4{
Tff7b72val Te6edf3intent Tff7b72=
Te6edf3IntentTb4b4b4(Te6edf3contextTb4b4b4, Te6edf3ClassTb4b4b4.Te6edf3forNameTb4b4b4(Ta5d6ff"Ta5d6fforg.meshtastic.app.MainActivityTa5d6ff"Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3apply Tb4b4b4{
Te6edf3flags Tff7b72= Te6edf3IntentTb4b4b4.Te6edf3FLAG_ACTIVITY_NEW_TASK Te6edf3or Te6edf3IntentTb4b4b4.Te6edf3FLAG_ACTIVITY_SINGLE_TOP
Tb4b4b4}
Te6edf3PendingIntentTb4b4b4.Te6edf3getActivityTb4b4b4(Te6edf3contextTb4b4b4, T79c0ff0Tb4b4b4, Te6edf3intentTb4b4b4, Te6edf3PendingIntentTb4b4b4.Te6edf3FLAG_IMMUTABLE Te6edf3or Te6edf3PendingIntentTb4b4b4.Te6edf3FLAG_UPDATE_CURRENTTb4b4b4)
Tb4b4b4}

Tff7b72private Tff7b72fun Td2a8ffcreateOpenMessageIntentTb4b4b4(Te6edf3contactKeyTb4b4b4: Tffa657StringTb4b4b4)Tb4b4b4: Te6edf3PendingIntent Tb4b4b4{
Tff7b72val Te6edf3deepLinkUri Tff7b72= Ta5d6ff"Tffd700$Te6edf3DEEP_LINK_BASE_URITa5d6ff/messages/Tffd700$Te6edf3contactKeyTa5d6ff"Tb4b4b4.Te6edf3toUriTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3deepLinkIntent Tff7b72=
Te6edf3IntentTb4b4b4(Te6edf3IntentTb4b4b4.Te6edf3ACTION_VIEWTb4b4b4, Te6edf3deepLinkUriTb4b4b4, Te6edf3contextTb4b4b4, Te6edf3ClassTb4b4b4.Te6edf3forNameTb4b4b4(Ta5d6ff"Ta5d6fforg.meshtastic.app.MainActivityTa5d6ff"Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3apply Tb4b4b4{
Te6edf3flags Tff7b72= Te6edf3IntentTb4b4b4.Te6edf3FLAG_ACTIVITY_SINGLE_TOP
Tb4b4b4}

Tff7b72return Te6edf3TaskStackBuilderTb4b4b4.Te6edf3createTb4b4b4(Te6edf3contextTb4b4b4)Tb4b4b4.Te6edf3run Tb4b4b4{
Te6edf3addNextIntentWithParentStackTb4b4b4(Te6edf3deepLinkIntentTb4b4b4)
Te6edf3getPendingIntentTb4b4b4(Te6edf3contactKeyTb4b4b4.Te6edf3hashCodeTb4b4b4(Tb4b4b4)Tb4b4b4, Te6edf3PendingIntentTb4b4b4.Te6edf3FLAG_IMMUTABLE Te6edf3or Te6edf3PendingIntentTb4b4b4.Te6edf3FLAG_UPDATE_CURRENTTb4b4b4)
Tb4b4b4}
Tb4b4b4}

Tff7b72private Tff7b72fun Td2a8ffcreateOpenWaypointIntentTb4b4b4(Te6edf3waypointIdTb4b4b4: Tffa657IntTb4b4b4)Tb4b4b4: Te6edf3PendingIntent Tb4b4b4{
Tff7b72val Te6edf3deepLinkUri Tff7b72= Ta5d6ff"Tffd700$Te6edf3DEEP_LINK_BASE_URITa5d6ff/map?waypointId=Tffd700$Te6edf3waypointIdTa5d6ff"Tb4b4b4.Te6edf3toUriTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3deepLinkIntent Tff7b72=
Te6edf3IntentTb4b4b4(Te6edf3IntentTb4b4b4.Te6edf3ACTION_VIEWTb4b4b4, Te6edf3deepLinkUriTb4b4b4, Te6edf3contextTb4b4b4, Te6edf3ClassTb4b4b4.Te6edf3forNameTb4b4b4(Ta5d6ff"Ta5d6fforg.meshtastic.app.MainActivityTa5d6ff"Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3apply Tb4b4b4{
Te6edf3flags Tff7b72= Te6edf3IntentTb4b4b4.Te6edf3FLAG_ACTIVITY_SINGLE_TOP
Tb4b4b4}

Tff7b72return Te6edf3TaskStackBuilderTb4b4b4.Te6edf3createTb4b4b4(Te6edf3contextTb4b4b4)Tb4b4b4.Te6edf3run Tb4b4b4{
Te6edf3addNextIntentWithParentStackTb4b4b4(Te6edf3deepLinkIntentTb4b4b4)
Te6edf3getPendingIntentTb4b4b4(Te6edf3waypointIdTb4b4b4, Te6edf3PendingIntentTb4b4b4.Te6edf3FLAG_IMMUTABLE Te6edf3or Te6edf3PendingIntentTb4b4b4.Te6edf3FLAG_UPDATE_CURRENTTb4b4b4)
Tb4b4b4}
Tb4b4b4}

Tff7b72private Tff7b72fun Td2a8ffcreateOpenNodeDetailIntentTb4b4b4(Te6edf3nodeNumTb4b4b4: Tffa657IntTb4b4b4)Tb4b4b4: Te6edf3PendingIntent Tb4b4b4{
Tff7b72val Te6edf3deepLinkUri Tff7b72= Ta5d6ff"Tffd700$Te6edf3DEEP_LINK_BASE_URITa5d6ff/nodes/Tffd700$Te6edf3nodeNumTa5d6ff"Tb4b4b4.Te6edf3toUriTb4b4b4(Tb4b4b4)
Tff7b72val Te6edf3deepLinkIntent Tff7b72=
Te6edf3IntentTb4b4b4(Te6edf3IntentTb4b4b4.Te6edf3ACTION_VIEWTb4b4b4, Te6edf3deepLinkUriTb4b4b4, Te6edf3contextTb4b4b4, Te6edf3ClassTb4b4b4.Te6edf3forNameTb4b4b4(Ta5d6ff"Ta5d6fforg.meshtastic.app.MainActivityTa5d6ff"Tb4b4b4)Tb4b4b4)Tb4b4b4.Te6edf3apply Tb4b4b4{
Te6edf3flags Tff7b72= Te6edf3IntentTb4b4b4.Te6edf3FLAG_ACTIVITY_SINGLE_TOP
Tb4b4b4}

Tff7b72return Te6edf3TaskStackBuilderTb4b4b4.Te6edf3createTb4b4b4(Te6edf3contextTb4b4b4)Tb4b4b4.Te6edf3run Tb4b4b4{
Te6edf3addNextIntentWithParentStackTb4b4b4(Te6edf3deepLinkIntentTb4b4b4)
Te6edf3getPendingIntentTb4b4b4(Te6edf3nodeNumTb4b4b4, Te6edf3PendingIntentTb4b4b4.Te6edf3FLAG_IMMUTABLE Te6edf3or Te6edf3PendingIntentTb4b4b4.Te6edf3FLAG_UPDATE_CURRENTTb4b4b4)
Tb4b4b4}
Tb4b4b4}

Tff7b72private Tff7b72suspend Tff7b72fun Td2a8ffcreateReplyActionTb4b4b4(Te6edf3contactKeyTb4b4b4: Tffa657StringTb4b4b4)Tb4b4b4: Te6edf3NotificationCompatTb4b4b4.Te6edf3Action Tb4b4b4{
Tff7b72val Te6edf3replyLabel Tff7b72= Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3replyTb4b4b4)
Tff7b72val Te6edf3remoteInput Tff7b72= Te6edf3RemoteInputTb4b4b4.Te6edf3BuilderTb4b4b4(Te6edf3KEY_TEXT_REPLYTb4b4b4)Tb4b4b4.Te6edf3setLabelTb4b4b4(Te6edf3replyLabelTb4b4b4)Tb4b4b4.Te6edf3buildTb4b4b4(Tb4b4b4)

Tff7b72val Te6edf3replyIntent Tff7b72=
Te6edf3IntentTb4b4b4(Te6edf3contextTb4b4b4, Te6edf3ReplyReceiverTff7b72::Te6edf3classTb4b4b4.Te6edf3javaTb4b4b4)Tb4b4b4.Te6edf3apply Tb4b4b4{
Te6edf3action Tff7b72= Te6edf3ReplyReceiverTb4b4b4.Te6edf3REPLY_ACTION
Te6edf3putExtraTb4b4b4(Te6edf3ReplyReceiverTb4b4b4.Te6edf3CONTACT_KEYTb4b4b4, Te6edf3contactKeyTb4b4b4)
Tb4b4b4}
Tff7b72val Te6edf3replyPendingIntent Tff7b72=
Te6edf3PendingIntentTb4b4b4.Te6edf3getBroadcastTb4b4b4(
Te6edf3contextTb4b4b4,
Te6edf3contactKeyTb4b4b4.Te6edf3hashCodeTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3replyIntentTb4b4b4,
Te6edf3PendingIntentTb4b4b4.Te6edf3FLAG_MUTABLE Te6edf3or Te6edf3PendingIntentTb4b4b4.Te6edf3FLAG_UPDATE_CURRENTTb4b4b4,
Tb4b4b4)

Tff7b72return Te6edf3NotificationCompatTb4b4b4.Te6edf3ActionTb4b4b4.Te6edf3BuilderTb4b4b4(Te6edf3androidTb4b4b4.Te6edf3RTb4b4b4.Te6edf3drawableTb4b4b4.Te6edf3ic_menu_sendTb4b4b4, Te6edf3replyLabelTb4b4b4, Te6edf3replyPendingIntentTb4b4b4)
Tb4b4b4.Te6edf3addRemoteInputTb4b4b4(Te6edf3remoteInputTb4b4b4)
T8b949e// Required for Android Auto to drive reply hands-free without opening any UI.
Tb4b4b4.Te6edf3setSemanticActionTb4b4b4(Te6edf3NotificationCompatTb4b4b4.Te6edf3ActionTb4b4b4.Te6edf3SEMANTIC_ACTION_REPLYTb4b4b4)
Tb4b4b4.Te6edf3setShowsUserInterfaceTb4b4b4(Tff7b72falseTb4b4b4)
Tb4b4b4.Te6edf3buildTb4b4b4(Tb4b4b4)
Tb4b4b4}

Tff7b72private Tff7b72suspend Tff7b72fun Td2a8ffcreateMarkAsReadActionTb4b4b4(Te6edf3contactKeyTb4b4b4: Tffa657StringTb4b4b4)Tb4b4b4: Te6edf3NotificationCompatTb4b4b4.Te6edf3Action Tb4b4b4{
Tff7b72val Te6edf3label Tff7b72= Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3mark_as_readTb4b4b4)
Tff7b72val Te6edf3intent Tff7b72=
Te6edf3IntentTb4b4b4(Te6edf3contextTb4b4b4, Te6edf3MarkAsReadReceiverTff7b72::Te6edf3classTb4b4b4.Te6edf3javaTb4b4b4)Tb4b4b4.Te6edf3apply Tb4b4b4{
Te6edf3action Tff7b72= Te6edf3MARK_AS_READ_ACTION
Te6edf3putExtraTb4b4b4(Te6edf3MarkAsReadReceiverTb4b4b4.Te6edf3CONTACT_KEYTb4b4b4, Te6edf3contactKeyTb4b4b4)
Tb4b4b4}
Tff7b72val Te6edf3pendingIntent Tff7b72=
Te6edf3PendingIntentTb4b4b4.Te6edf3getBroadcastTb4b4b4(
Te6edf3contextTb4b4b4,
Te6edf3contactKeyTb4b4b4.Te6edf3hashCodeTb4b4b4(Tb4b4b4)Tb4b4b4,
Te6edf3intentTb4b4b4,
Te6edf3PendingIntentTb4b4b4.Te6edf3FLAG_UPDATE_CURRENT Te6edf3or Te6edf3PendingIntentTb4b4b4.Te6edf3FLAG_IMMUTABLETb4b4b4,
Tb4b4b4)

Tff7b72return Te6edf3NotificationCompatTb4b4b4.Te6edf3ActionTb4b4b4.Te6edf3BuilderTb4b4b4(Te6edf3androidTb4b4b4.Te6edf3RTb4b4b4.Te6edf3drawableTb4b4b4.Te6edf3ic_menu_viewTb4b4b4, Te6edf3labelTb4b4b4, Te6edf3pendingIntentTb4b4b4)
T8b949e// Required for Android Auto to mark a conversation read hands-free without opening any UI.
Tb4b4b4.Te6edf3setSemanticActionTb4b4b4(Te6edf3NotificationCompatTb4b4b4.Te6edf3ActionTb4b4b4.Te6edf3SEMANTIC_ACTION_MARK_AS_READTb4b4b4)
Tb4b4b4.Te6edf3setShowsUserInterfaceTb4b4b4(Tff7b72falseTb4b4b4)
Tb4b4b4.Te6edf3buildTb4b4b4(Tb4b4b4)
Tb4b4b4}

Tff7b72private Tff7b72fun Td2a8ffcreateReactionActionTb4b4b4(
Te6edf3contactKeyTb4b4b4: Tffa657StringTb4b4b4,
Te6edf3packetIdTb4b4b4: Tffa657IntTb4b4b4,
Te6edf3toIdTb4b4b4: Tffa657StringTb4b4b4,
Te6edf3channelIndexTb4b4b4: Tffa657IntTb4b4b4,
Tb4b4b4)Tb4b4b4: Te6edf3NotificationCompatTb4b4b4.Te6edf3Action Tb4b4b4{
Tff7b72val Te6edf3label Tff7b72= Ta5d6ff"Ta5d6ff👍Ta5d6ff"
Tff7b72val Te6edf3intent Tff7b72=
Te6edf3IntentTb4b4b4(Te6edf3contextTb4b4b4, Te6edf3ReactionReceiverTff7b72::Te6edf3classTb4b4b4.Te6edf3javaTb4b4b4)Tb4b4b4.Te6edf3apply Tb4b4b4{
Te6edf3action Tff7b72= Te6edf3REACT_ACTION
Te6edf3putExtraTb4b4b4(Te6edf3ReactionReceiverTb4b4b4.Te6edf3EXTRA_CONTACT_KEYTb4b4b4, Te6edf3contactKeyTb4b4b4)
Te6edf3putExtraTb4b4b4(Te6edf3ReactionReceiverTb4b4b4.Te6edf3EXTRA_REPLY_IDTb4b4b4, Te6edf3packetIdTb4b4b4)
Te6edf3putExtraTb4b4b4(Te6edf3ReactionReceiverTb4b4b4.Te6edf3EXTRA_TO_IDTb4b4b4, Te6edf3toIdTb4b4b4)
Te6edf3putExtraTb4b4b4(Te6edf3ReactionReceiverTb4b4b4.Te6edf3EXTRA_CHANNEL_INDEXTb4b4b4, Te6edf3channelIndexTb4b4b4)
Te6edf3putExtraTb4b4b4(Te6edf3ReactionReceiverTb4b4b4.Te6edf3EXTRA_EMOJITb4b4b4, Ta5d6ff"Ta5d6ff👍Ta5d6ff"Tb4b4b4)
Tb4b4b4}
Tff7b72val Te6edf3pendingIntent Tff7b72=
Te6edf3PendingIntentTb4b4b4.Te6edf3getBroadcastTb4b4b4(
Te6edf3contextTb4b4b4,
Te6edf3packetIdTb4b4b4,
Te6edf3intentTb4b4b4,
Te6edf3PendingIntentTb4b4b4.Te6edf3FLAG_UPDATE_CURRENT Te6edf3or Te6edf3PendingIntentTb4b4b4.Te6edf3FLAG_IMMUTABLETb4b4b4,
Tb4b4b4)

Tff7b72return Te6edf3NotificationCompatTb4b4b4.Te6edf3ActionTb4b4b4.Te6edf3BuilderTb4b4b4(Te6edf3androidTb4b4b4.Te6edf3RTb4b4b4.Te6edf3drawableTb4b4b4.Te6edf3ic_menu_addTb4b4b4, Te6edf3labelTb4b4b4, Te6edf3pendingIntentTb4b4b4)Tb4b4b4.Te6edf3buildTb4b4b4(Tb4b4b4)
Tb4b4b4}

Tff7b72private Tff7b72fun Td2a8ffcommonBuilderTb4b4b4(
Te6edf3typeTb4b4b4: Te6edf3NotificationTypeTb4b4b4,
Te6edf3contentIntentTb4b4b4: Te6edf3PendingIntent? Tff7b72= Tff7b72nullTb4b4b4,
Tb4b4b4)Tb4b4b4: Te6edf3NotificationCompatTb4b4b4.Te6edf3Builder Tb4b4b4{
Tff7b72val Te6edf3smallIcon Tff7b72= Te6edf3drawableTb4b4b4.Te6edf3meshtastic_ic_notification

Tff7b72return Te6edf3NotificationCompatTb4b4b4.Te6edf3BuilderTb4b4b4(Te6edf3contextTb4b4b4, Te6edf3typeTb4b4b4.Te6edf3channelIdTb4b4b4)
Tb4b4b4.Te6edf3setSmallIconTb4b4b4(Te6edf3smallIconTb4b4b4)
Tb4b4b4.Te6edf3setColorTb4b4b4(Te6edf3NOTIFICATION_COLORTb4b4b4)
Tb4b4b4.Te6edf3setVisibilityTb4b4b4(Te6edf3NotificationCompatTb4b4b4.Te6edf3VISIBILITY_PUBLICTb4b4b4)
Tb4b4b4.Te6edf3setContentIntentTb4b4b4(Te6edf3contentIntent Tff7b72?: Te6edf3openAppIntentTb4b4b4)
Tb4b4b4}

T8b949e// endregion

T8b949e// region Extension Functions (Localized)

Tff7b72private Tff7b72suspend Tff7b72fun Te6edf3LocalStatsTb4b4b4.Td2a8ffformatToStringSuspendTb4b4b4(Te6edf3batteryLevelTb4b4b4: Tffa657Int? Tff7b72= Tff7b72nullTb4b4b4)Tb4b4b4: Tffa657String Tb4b4b4{
Tff7b72val Te6edf3parts Tff7b72= Te6edf3mutableListOfTff7b72<Tffa657StringTff7b72>Tb4b4b4(Tb4b4b4)
Te6edf3batteryLevelTff7b72?.Te6edf3let Tb4b4b4{
Tff7b72if Tb4b4b4(Tffa657it Tff7b72> Te6edf3MAX_BATTERY_LEVELTb4b4b4) Tb4b4b4{
Te6edf3partsTb4b4b4.Te6edf3addTb4b4b4(Te6edf3BULLET Tff7b72+ Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3poweredTb4b4b4)Tb4b4b4)
Tb4b4b4} Tff7b72else Tb4b4b4{
Te6edf3partsTb4b4b4.Te6edf3addTb4b4b4(Te6edf3BULLET Tff7b72+ Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3local_stats_batteryTb4b4b4, Tffa657itTb4b4b4)Tb4b4b4)
Tb4b4b4}
Tb4b4b4}
Te6edf3partsTb4b4b4.Te6edf3addTb4b4b4(Te6edf3BULLET Tff7b72+ Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3local_stats_nodesTb4b4b4, Te6edf3num_online_nodesTb4b4b4, Te6edf3num_total_nodesTb4b4b4)Tb4b4b4)
Te6edf3partsTb4b4b4.Te6edf3addTb4b4b4(Te6edf3BULLET Tff7b72+ Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3local_stats_uptimeTb4b4b4, Te6edf3formatUptimeTb4b4b4(Te6edf3uptime_secondsTb4b4b4)Tb4b4b4)Tb4b4b4)
Te6edf3partsTb4b4b4.Te6edf3addTb4b4b4(
Te6edf3BULLET Tff7b72+
Te6edf3getStringSuspendTb4b4b4(
Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3local_stats_utilizationTb4b4b4,
Te6edf3NumberFormatterTb4b4b4.Te6edf3formatTb4b4b4(Te6edf3channel_utilizationTb4b4b4.Te6edf3toDoubleTb4b4b4(Tb4b4b4)Tb4b4b4, T79c0ff2Tb4b4b4)Tb4b4b4,
Te6edf3NumberFormatterTb4b4b4.Te6edf3formatTb4b4b4(Te6edf3air_util_txTb4b4b4.Te6edf3toDoubleTb4b4b4(Tb4b4b4)Tb4b4b4, T79c0ff2Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)

Tff7b72if Tb4b4b4(Te6edf3heap_free_bytes Tff7b72> T79c0ff0 Tff7b72|Tff7b72| Te6edf3heap_total_bytes Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3partsTb4b4b4.Te6edf3addTb4b4b4(
Te6edf3BULLET Tff7b72+
Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3local_stats_heapTb4b4b4) Tff7b72+
Ta5d6ff"Ta5d6ff: Ta5d6ff" Tff7b72+
Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3local_stats_heap_valueTb4b4b4, Te6edf3heap_free_bytesTb4b4b4, Te6edf3heap_total_bytesTb4b4b4)Tb4b4b4,
Tb4b4b4)
Tb4b4b4}

T8b949e// Traffic Stats
Tff7b72if Tb4b4b4(Te6edf3num_packets_tx Tff7b72> T79c0ff0 Tff7b72|Tff7b72| Te6edf3num_packets_rx Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3partsTb4b4b4.Te6edf3addTb4b4b4(
Te6edf3BULLET Tff7b72+ Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3local_stats_trafficTb4b4b4, Te6edf3num_packets_txTb4b4b4, Te6edf3num_packets_rxTb4b4b4, Te6edf3num_rx_dupeTb4b4b4)Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3num_tx_relay Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3partsTb4b4b4.Te6edf3addTb4b4b4(Te6edf3BULLET Tff7b72+ Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3local_stats_relaysTb4b4b4, Te6edf3num_tx_relayTb4b4b4, Te6edf3num_tx_relay_canceledTb4b4b4)Tb4b4b4)
Tb4b4b4}

T8b949e// Diagnostic Fields
Tff7b72val Te6edf3diagnosticParts Tff7b72= Te6edf3mutableListOfTff7b72<Tffa657StringTff7b72>Tb4b4b4(Tb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3noise_floor Tff7b72!Tff7b72= T79c0ff0Tb4b4b4) Te6edf3diagnosticPartsTb4b4b4.Te6edf3addTb4b4b4(Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3local_stats_noiseTb4b4b4, Te6edf3noise_floorTb4b4b4)Tb4b4b4)
Tff7b72if Tb4b4b4(Te6edf3num_packets_rx_bad Tff7b72> T79c0ff0Tb4b4b4) Tb4b4b4{
Te6edf3diagnosticPartsTb4b4b4.Te6edf3addTb4b4b4(Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3local_stats_badTb4b4b4, Te6edf3num_packets_rx_badTb4b4b4)Tb4b4b4)
Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3num_tx_dropped Tff7b72> T79c0ff0Tb4b4b4) Te6edf3diagnosticPartsTb4b4b4.Te6edf3addTb4b4b4(Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3local_stats_droppedTb4b4b4, Te6edf3num_tx_droppedTb4b4b4)Tb4b4b4)

Tff7b72if Tb4b4b4(Te6edf3diagnosticPartsTb4b4b4.Te6edf3isNotEmptyTb4b4b4(Tb4b4b4)Tb4b4b4) Tb4b4b4{
Te6edf3partsTb4b4b4.Te6edf3addTb4b4b4(
Te6edf3BULLET Tff7b72+
Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3local_stats_diagnostics_prefixTb4b4b4, Te6edf3diagnosticPartsTb4b4b4.Te6edf3joinToStringTb4b4b4(Ta5d6ff"Ta5d6ff | Ta5d6ff"Tb4b4b4)Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tb4b4b4}

Tff7b72return Te6edf3partsTb4b4b4.Te6edf3joinToStringTb4b4b4(Ta5d6ff"Ta5d6ff\Ta5d6ffnTa5d6ff"Tb4b4b4)
Tb4b4b4}

Tff7b72private Tff7b72suspend Tff7b72fun Te6edf3DeviceMetricsTb4b4b4.Td2a8ffformatToStringSuspendTb4b4b4(Tb4b4b4)Tb4b4b4: Tffa657String Tb4b4b4{
Tff7b72val Te6edf3parts Tff7b72= Te6edf3mutableListOfTff7b72<Tffa657StringTff7b72>Tb4b4b4(Tb4b4b4)
Te6edf3battery_levelTff7b72?.Te6edf3let Tb4b4b4{ Te6edf3partsTb4b4b4.Te6edf3addTb4b4b4(Te6edf3BULLET Tff7b72+ Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3local_stats_batteryTb4b4b4, Tffa657itTb4b4b4)Tb4b4b4) Tb4b4b4}
Te6edf3uptime_secondsTff7b72?.Te6edf3let Tb4b4b4{ Te6edf3partsTb4b4b4.Te6edf3addTb4b4b4(Te6edf3BULLET Tff7b72+ Te6edf3getStringSuspendTb4b4b4(Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3local_stats_uptimeTb4b4b4, Te6edf3formatUptimeTb4b4b4(Tffa657itTb4b4b4)Tb4b4b4)Tb4b4b4) Tb4b4b4}
Tff7b72if Tb4b4b4(Te6edf3channel_utilization Tff7b72!Tff7b72= Tff7b72null Tff7b72|Tff7b72| Te6edf3air_util_tx Tff7b72!Tff7b72= Tff7b72nullTb4b4b4) Tb4b4b4{
Te6edf3partsTb4b4b4.Te6edf3addTb4b4b4(
Te6edf3BULLET Tff7b72+
Te6edf3getStringSuspendTb4b4b4(
Te6edf3ResTb4b4b4.Te6edf3stringTb4b4b4.Te6edf3local_stats_utilizationTb4b4b4,
Te6edf3NumberFormatterTb4b4b4.Te6edf3formatTb4b4b4(Tb4b4b4(Te6edf3channel_utilization Tff7b72?: T79c0ff0fTb4b4b4)Tb4b4b4.Te6edf3toDoubleTb4b4b4(Tb4b4b4)Tb4b4b4, T79c0ff2Tb4b4b4)Tb4b4b4,
Te6edf3NumberFormatterTb4b4b4.Te6edf3formatTb4b4b4(Tb4b4b4(Te6edf3air_util_tx Tff7b72?: T79c0ff0fTb4b4b4)Tb4b4b4.Te6edf3toDoubleTb4b4b4(Tb4b4b4)Tb4b4b4, T79c0ff2Tb4b4b4)Tb4b4b4,
Tb4b4b4)Tb4b4b4,
Tb4b4b4)
Tb4b4b4}
Tff7b72return Te6edf3partsTb4b4b4.Te6edf3joinToStringTb4b4b4(Ta5d6ff"Ta5d6ff\Ta5d6ffnTa5d6ff"Tb4b4b4)
Tb4b4b4}

T8b949e// endregion
Tb4b4b4}

Served by rngit 1.5.0 - Generated in 0.32s